00001
00022 #include "lo/LocatedObject.h"
00023 #define ID_WORLD 1
00024
00025 #define MAX_TREE_HEIGHT 200
00026
00027
00028 namespace jlo
00029 {
00030
00031
00032 LocatedObject::LocatedObject(LazyLocatedObjectLoader* loader) :
00033 m_uniqueID(ID_WORLD),
00034 m_parentID(0),
00035 m_lazyObjLoader(loader)
00036 {
00037 }
00038 LocatedObject::LocatedObject(LazyLocatedObjectLoader* loader, unsigned long id, unsigned long parent_id, const Matrix &matrix , const Matrix &covariance) :
00039 m_uniqueID(id),
00040 m_parentID(parent_id),
00041 m_lazyObjLoader(loader)
00042 {
00043 Set(matrix, covariance);
00044 }
00045
00046 LocatedObject::LocatedObject(LazyLocatedObjectLoader* loader, unsigned long id, unsigned long parent_id,
00047 double x , double y , double z ,
00048 double roll , double pitch , double yaw ,
00049 double sigmaX , double sigmaY , double sigmaZ ,
00050 double sigmaRoll , double sigmaPitch , double sigmaYaw ) :
00051 m_uniqueID(id),
00052 m_parentID(parent_id),
00053 m_lazyObjLoader(loader)
00054 {
00055 ColumnVector v(3), rpy_v(3);
00056 v << x << y << z;
00057 rpy_v << roll << pitch << yaw;
00058
00059 DiagonalMatrix temp(6);
00060 temp << sigmaX << sigmaY << sigmaZ << sigmaRoll << sigmaPitch << sigmaYaw;
00061 Matrix temp2=temp;
00062 Set(rpy(rpy_v) * trans(v), temp2);
00063 }
00064
00065
00066
00067
00068
00069 bool LocatedObject::CheckWorldCoordinates(const unsigned long &levelsTogo) const
00070 {
00071 if(levelsTogo > 0 )
00072 {
00073 LocatedObject* relation = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*this));
00074 if(relation == NULL || relation->m_uniqueID == ID_WORLD)
00075 return true;
00076 else
00077 return relation->CheckWorldCoordinates(levelsTogo - 1);
00078 }
00079 else
00080 return false;
00081 }
00082
00084 unsigned long LocatedObject::FindCommonFather(const LocatedObject* bigObject) const
00085 {
00086 if(bigObject == NULL)
00087 return ID_WORLD;
00088 if(bigObject->m_uniqueID == ID_WORLD || m_uniqueID == ID_WORLD)
00089 return ID_WORLD;
00090 const LocatedObject* relation = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*this));
00091
00092
00093 const LocatedObject* loc = relation;
00094 while(loc != NULL)
00095 {
00096 if(loc->m_uniqueID == bigObject->m_uniqueID)
00097 return bigObject->m_uniqueID;
00098 else
00099 {
00100 loc = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*loc));
00101 }
00102 }
00103 return FindCommonFather(((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*bigObject)));
00104 }
00105
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00129 ReturnMatrix LocatedObject::GetMatrix (const unsigned long &id_to_stop ) {
00130 Matrix m;
00131 if(m_uniqueID == 0)
00132 {
00133 printf("Null id !!\n");
00134 m=IdentityMatrix(4);
00135 }
00136 else if(m_uniqueID == ID_WORLD || id_to_stop == m_uniqueID)
00137 m=IdentityMatrix(4);
00138 else
00139 {
00140 LocatedObject* relation = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*this));
00141 if(id_to_stop == 0 && relation != NULL)
00142 {
00143 m = Get();
00144 }
00145 else
00146 {
00147 if(relation != NULL && id_to_stop != m_uniqueID && relation->m_uniqueID != 0)
00148 {
00149 m = relation->GetMatrix(id_to_stop) * Get();
00150 } else {
00151
00152 m=IdentityMatrix(4);
00153 }
00154 }
00155 }
00156 m.release();
00157 return m;
00158 }
00159
00160 ReturnMatrix LocatedObject::GetMatrix (LocatedObject &obj_to_stop )
00161 {
00162 unsigned long id = obj_to_stop.FindCommonFather(this);
00163 if(id == ID_WORLD)
00164 id = FindCommonFather(&obj_to_stop);
00165 Matrix m, n;
00166 m = obj_to_stop.GetInvMatrix(id);
00167 n = GetMatrix(id);
00168
00169 m = m * n;
00170 m.release();
00171 return m;
00172 }
00173
00174
00175 ReturnMatrix LocatedObject::GetInvMatrix (const unsigned long &id_to_stop ) {
00176 Matrix m;
00177 LocatedObject* relation = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*this));
00178 if(id_to_stop == 0 && relation != NULL)
00179 {
00180 m = GetInv();
00181 }
00182 else if(relation != NULL && id_to_stop != m_uniqueID)
00183 {
00184 m = GetInv() *relation->GetInvMatrix(id_to_stop);
00185 } else {
00186 m=IdentityMatrix(4);
00187 }
00188 m.release();
00189 return m;
00190 }
00191
00192 ReturnMatrix LocatedObject::GetInvMatrix ( LocatedObject &obj_to_stop )
00193 {
00194 unsigned long id = obj_to_stop.FindCommonFather(this);
00195 Matrix m, n;
00196 m = obj_to_stop.GetMatrix(id);
00197 n = GetInvMatrix(id);
00198
00199 m = n * m;
00200 m.release();
00201 return m;
00202 }
00206 ReturnMatrix LocatedObject::GetOrigin (LocatedObject &obj_to_stop )
00207 {
00208 return GetOrigin(obj_to_stop.m_uniqueID);
00209 }
00210
00211 ReturnMatrix LocatedObject::GetOrigin(const unsigned long &id_to_stop)
00212 {
00213 Matrix m = GetMatrix(id_to_stop);
00214 ColumnVector t(4);
00215 double scale = m.element(3,3);
00216 t << m.element(0,3)/ scale << m.element(1,3)/ scale << m.element(2,3) / scale << 1;
00217 t.release();
00218 return t;
00219 }
00223 ReturnMatrix LocatedObject::GetRotation (LocatedObject &obj_to_stop )
00224 {
00225 return GetRotation(obj_to_stop.m_uniqueID);
00226 }
00227 ReturnMatrix LocatedObject::GetRotation (const unsigned long &obj_to_stop)
00228 {
00229 Matrix m = GetMatrix(obj_to_stop);
00230 ColumnVector rpyMat = irpy(m);
00231 rpyMat.release();
00232 return rpyMat;
00233 }
00234
00235 inline ReturnMatrix LocatedObject::TransformSixVec(const ColumnVector& point, const Matrix& hom) const
00236 {
00237
00238 ColumnVector t(3), rot(3);
00239 t = point.rows(1,3);
00240 rot = point.rows(4,6);
00241 Matrix m(4,4);
00242 m = rpy(rot);
00243 m.element(0,3) = t.element(0);
00244 m.element(1,3) = t.element(1);
00245 m.element(2,3) = t.element(2);
00246
00247
00248 m = hom*m;
00249
00250 ColumnVector rpyRot(3);
00251 rpyRot = irpy(m);
00252 ColumnVector ret(6);
00253 ret << m.element(0,3) << m.element(1,3) << m.element(2,3) << rpyRot.element(0)<< rpyRot.element(1)<< rpyRot.element(2);
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 ret.release();
00273 return ret;
00274 }
00275
00276 inline double MinAngleDist(const double &alpha, const double &beta)
00277 {
00278 double temp = min (fabs((alpha) - (beta)), fabs( (min((alpha) ,(beta)) + 2*M_PI) -max(alpha, beta)));
00279
00280 return temp;
00281 }
00282
00283 inline void ApplyRotationMean(ColumnVector &point, const double &rot_x, const double &rot_y, const double &rot_z)
00284 {
00285 Real& x_in_vec = point.element(3);
00286 Real& y_in_vec = point.element(4);
00287 Real& z_in_vec = point.element(5);
00288
00289 x_in_vec = MinAngleDist(rot_x, x_in_vec);
00290 y_in_vec = MinAngleDist(rot_y, y_in_vec);
00291 z_in_vec = MinAngleDist(rot_z, z_in_vec);
00292 }
00293
00294 inline void MatSqrt(Matrix& hom)
00295 {
00296 Real* pt = hom.Store();
00297 for(int i = 0; i < hom.size(); i++)
00298 {
00299 pt[i] = sqrt(fabs(pt[i])) / 2;
00300 }
00301 }
00302 inline ReturnMatrix LocatedObject::CalcNewCov(const DiagonalMatrix& eigenValues, const Matrix& eigenVectors, const Matrix& hom) const
00303 {
00304
00305 ColumnVector v(6), rpyRot(3);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 ColumnVector vNull(6);
00316 vNull << 0 << 0<< 0<< 0<< 0<< 0;
00317
00318
00319
00320 Matrix m(6, 6);
00321
00322 memset((Real*)m.Store(), 0, sizeof(Real) * 36);
00323 double norm_rot_x = 0.0, norm_rot_y = 0.0, norm_rot_z = 0.0;
00324 ColumnVector point1[6], point2[6];
00325
00326
00327 for(int i = 0; i <= 5; i++)
00328 {
00329
00330 ColumnVector ExtremPlus, ExtremeMinus;
00331 if(eigenValues.element(i) > 1.0)
00332 eigenValues.Store()[i] = 1.0;
00333
00334 point1[i] = TransformSixVec(eigenValues.element(i)*eigenVectors.column(i+1), hom);
00335 point2[i] = TransformSixVec(-eigenValues.element(i)*eigenVectors.column(i+1), hom);
00336
00337
00338
00339
00340
00341
00342 }
00343 vNull = TransformSixVec(vNull, hom);
00344 norm_rot_x = vNull.element(3);
00345 norm_rot_y = vNull.element(4);
00346 norm_rot_z = vNull.element(5);
00347 for(int i = 0; i <= 5; i++)
00348 {
00349 ApplyRotationMean(point1[i], norm_rot_x, norm_rot_y, norm_rot_z);
00350 ApplyRotationMean(point2[i], norm_rot_x, norm_rot_y, norm_rot_z);
00351
00352
00353 m += point1[i] * point1[i].t();
00354 m += point2[i] * point2[i].t();
00355
00356
00357 double cross_check = sqrt(m.sum_square());
00358 if(cross_check > 6.0)
00359 {
00360
00361
00362 }
00363
00364
00365
00366
00367 }
00368 MatSqrt(m);
00369
00370
00371 double cross_check = sqrt(m.sum_square());
00372 if(cross_check > 6.0)
00373 {
00374
00375
00376
00377 }
00378 m.release();
00379 return m;
00380 }
00381
00382 inline bool eqd(const double &d1, const double &d2)
00383 {
00384 if(fabs(d1-d2) < 0.0000000001)
00385 {
00386 return true;
00387 }
00388 return false;
00389 }
00390
00391 inline bool IsIdentity(const Matrix m)
00392 {
00393
00394
00395 for(int i = 0; i < m.nrows(); i++)
00396 for(int j= 0; j < m.ncols(); j++)
00397 if(!eqd(m.element(i,j), ((i == j) ? 1.0 : 0.0)))
00398 {
00399
00400 return false;
00401 }
00402
00403 return true;
00404 }
00405 #define EIGENVECTORS_ARE_SCALED
00406 inline ReturnMatrix LocatedObject::UnscentedTrans(const Matrix& cov, const Matrix& mean, const Matrix& hom) const
00407 {
00408 try
00409 {
00410 int i = cov.nrows() * cov.ncols() ;
00411 if(i != 0 && !cov.is_zero() && !IsIdentity(hom))
00412 {
00413 DiagonalMatrix D;
00414 Matrix U, V;
00415
00416 SVD(cov, D, U, V);
00417
00418 #ifdef EIGENVECTORS_ARE_SCALED
00419 #else
00420 if(D.maximum() >= 1.0)
00421 printf("Undefined Behaviour in Unscented Trans!\n");
00422 #endif
00423
00424 Matrix hom_d = rpy(irpy(mean*hom));
00425
00426 Matrix m = CalcNewCov(D, U, hom_d);
00427 m.release();
00428 return m;
00429 }
00430
00431 }
00432 catch(...)
00433 {
00434 printf("Error in LocatedObject::UnscentedTrans\n");
00435 }
00436 return cov;
00437 }
00442 ReturnMatrix LocatedObject::GetCovarianceMatrix (const unsigned long &id_to_stop )
00443 {
00444 Matrix m;
00445 if(m_uniqueID == ID_WORLD || id_to_stop == m_uniqueID)
00446 {
00447 m = Matrix(6, 6);
00448 memset((Real*)m.Store(), 0, sizeof(Real) * 36);
00449 }
00450 else if (id_to_stop == 0)
00451 {
00452 return GetCovariance();
00453 }
00454 else
00455 {
00456 LocatedObject* relation = m_lazyObjLoader->GetParent(*this);
00457 Matrix n, n2;
00458 Matrix cov1, cov2;
00459 try
00460 {
00461 cov1 = GetCovariance();
00462 cov2 = relation->GetCovarianceMatrix(id_to_stop);
00463 }
00464 catch(...)
00465 {
00466 printf("Error in LocatedObject::GetCovarianceMatrix, inner\n");
00467 }
00468 if(cov1.is_zero() && cov2.is_zero())
00469 {
00470 m = cov1;
00471 }
00472 else
00473 {
00474 try
00475 {
00476 n = relation->GetInvMatrix(id_to_stop);
00477
00478 n2 = GetMatrix();
00479
00480
00481 try
00482 {
00483 m = cov1 + UnscentedTrans(cov2, n, n2);
00484 }
00485 catch(...)
00486 {
00487 printf("Error in sum cov2 + UnscentedTrans (%d,%d %d )\ncov2:\n", m_uniqueID, relation->m_uniqueID, id_to_stop);
00488 cout << cov2 << endl;
00489 cout << "cov1:\n" << cov1 << endl;
00490 cout << "n2, n\n" << n2 << endl << n << endl;
00491 cout << "results of unscent:"<< UnscentedTrans(cov1, n2, n);
00492
00493 }
00494 }
00495 catch(...)
00496 {
00497 printf("Error in LocatedObject::GetCovarianceMatrix, lower\n");
00498 }
00499 }
00500 if(m.size() != 36)
00501 {
00502 printf("Error calculating cov for %d\n", m_uniqueID);
00503 }
00504 }
00505 m.release();
00506 return m;
00507 }
00508
00509 ReturnMatrix LocatedObject::GetCovarianceMatrix (LocatedObject &obj_to_stop )
00510 {
00511
00512 unsigned long id = obj_to_stop.FindCommonFather(this);
00513 Matrix cov1, cov2;
00514 Matrix n, n2;
00515 try
00516 {
00517 cov2 = obj_to_stop.GetCovarianceMatrix(id);
00518 cov1 = GetCovarianceMatrix(id);
00519 }
00520 catch(...)
00521 {
00522 printf("Error in LocatedObject::GetCovarianceMatrix\n");
00523 }
00524 if(!cov1.is_zero())
00525 {
00526 n = obj_to_stop.GetInvMatrix(id);
00527 n2 = GetMatrix(id);
00528
00529 cov1 = cov1 + UnscentedTrans(cov2, n, n2);
00530 }
00531 cov1.release();
00532 return cov1;
00533 }
00534
00535
00536 double LocatedObject::CompareLo(LocatedObject &obj_to_stop )
00537 {
00538 double comp = 1.0;
00539
00540 Matrix cov = GetCovarianceMatrix(obj_to_stop);
00541 Matrix pos = GetMatrix(obj_to_stop);
00542 ColumnVector rot = irpy(pos);
00543 ColumnVector xyz(3);
00544 xyz << pos.element(0,3)<< pos.element(1,3) << pos.element(2,3);
00545 double dist[6];
00546
00547 dist[0] = (fabs(xyz.element(0)) - fabs(cov.element(0,0))) > 0 ? 2 : fabs(xyz.element(0)) + fabs(cov.element(0,0)) / 2;
00548 dist[1] = (fabs(xyz.element(1)) - fabs(cov.element(1,1))) > 0 ? 2 : fabs(xyz.element(1)) + fabs(cov.element(1,1)) / 2;
00549 dist[2] = (fabs(xyz.element(2)) - fabs(cov.element(2,2))) > 0 ? 2 : fabs(xyz.element(2)) + fabs(cov.element(2,2)) / 2;
00550 dist[3] = (fabs(rot.element(0)) - fabs(cov.element(3,3))) > 0 ? 2 : fabs(rot.element(0)) + fabs(cov.element(3,3)) / 2;
00551 dist[4] = (fabs(rot.element(1)) - fabs(cov.element(4,4))) > 0 ? 2 : fabs(rot.element(1)) + fabs(cov.element(4,4)) / 2;
00552 dist[5] = (fabs(rot.element(2)) - fabs(cov.element(5,5))) > 0 ? 2 : fabs(rot.element(2)) + fabs(cov.element(5,5)) / 2;
00553
00554
00555
00556 for(int i = 0; i < 6; i++)
00557 {
00558 comp += dist[i];
00559 }
00560 return 1 / comp - 1/12;
00561 }
00562
00563
00567 ReturnMatrix LocatedObject::Get ( ) {
00568 return m_relativePosition;
00569 }
00570
00571
00575 ReturnMatrix LocatedObject::GetCovariance ( )
00576 {
00577 return m_covariance;
00578 }
00579
00583 ReturnMatrix LocatedObject::GetInv ( )
00584 {
00585 return m_invRelativePosition;
00586 }
00587
00588
00592 unsigned long LocatedObject::Set(const Matrix &matrix, const Matrix &covMatrix )
00593 {
00594 m_relativePosition = matrix;
00595 if(matrix.nrows() != 0)
00596 {
00597 try
00598 {
00599
00600 ColumnVector v = irpy (matrix);
00601 Matrix m = rpy(v);
00602 m.element(0,3) = matrix.element(0,3);
00603 m.element(1,3) = matrix.element(1,3);
00604 m.element(2,3) = matrix.element(2,3);
00605 m_invRelativePosition = m.i();
00606
00607
00608
00609 }
00610 catch(...)
00611 {
00612 m_invRelativePosition = matrix;
00613 }
00614 }
00615 m_covariance = covMatrix;
00616 return RELOCATE_OBJECT;
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 }
00629
00630 unsigned long LocatedObject::Move(const Matrix &matrix, const Matrix& covMatrix)
00631 {
00632 LocatedObject* relation = ((m_uniqueID == ID_WORLD) ? NULL : m_lazyObjLoader->GetParent(*this));
00633 Set(matrix, covMatrix);
00634 return NO_MOVE;
00635 }
00636
00637 void LocatedObject::TransformPointLocally(const double& x_in, const double& y_in, const double& z_in, double& x_out, double& y_out, double& z_out, const double& scale)
00638 {
00639 Matrix m = GetMatrix();
00640 ColumnVector d(4);
00641 d << x_in / scale << y_in / scale << z_in / scale<< 1;
00642 ColumnVector f = m * d;
00643
00644 x_out = f.element(0);
00645 y_out = f.element(1);
00646 z_out = f.element(2);
00647
00648 }
00649
00650 }