collisiondetectors/CD_Swiftpp.cpp

Go to the documentation of this file.
00001 // CD_Swiftpp.cpp
00002 
00003 #include "robots/r_openchain.h"
00004 #include "CollisionDetectors/CD_Swiftpp.h"
00005 #include "geometry/Facet.h"
00006 #include "geometry/ObjectGroup.h"
00007 #include "Kinematics/LinkBase.h"
00008 #include "Universe/universe.h"
00009 #include "geometry/geo_rangesensor/Range_Sensor.h"
00010 #include "synchronization/semaphore.h"
00011 
00012 #include <direct.h> 
00013 #include <sys/types.h>
00014 #include <sys/stat.h>
00015 #include "SWIFTpp/include/SWIFT.h"
00016 #include "SWIFTpp/decomposer/include/gui.h"
00017 
00018 static const double OBS_TOL             = 1e-3;     
00019 static const char POLY[]        = "POLY\n\n";   // first word in .poly file
00020 static const char POLYEXT[]     = ".poly";  
00021 static const char HIEREXT[]     = ".chr";   // hierarchy file extension
00022 static const char FILENAME[]    = "object"; // poly file names: object##.poly
00023 
00024 // decomposer variables
00025 bool jitter = false;
00026 SWIFT_Real jampl = 0.0;
00027 bool ef = false;
00028 char* ef_filename = NULL;
00029 SWIFT_Real edge_flip_tol = 0.0; 
00030 bool dfs = false; 
00031 bool bfs = false; 
00032 bool w = false;
00033 bool one_piece = false; 
00034 char* decomp_filename = NULL; 
00035 bool hierarchy = true; 
00036 char* hier_filename = NULL; 
00037 SPLIT_TYPE split = MIDPOINT; 
00038 
00039 
00040 CD_Swiftpp::CD_Swiftpp (const Universe& universe)
00041 : 
00042     m_pUniversePointer( NULL ),
00043         CollisionDetectorBase( universe ),
00044         CD_BasicStyle( universe ),
00045         CD_Linear( universe ),
00046         CD_LinearContinuous( universe ),
00047         m_dObsTol(OBS_TOL)
00048 {
00049     m_pSwiftScene = new SWIFT_Scene;
00050     
00051     //go through all the entities that are in the entity list, 
00052     //and add all the meshes to the swift
00053         bool success = true ;
00054         for( int j = 0; j < entities.size(); j++ )
00055         {
00056                 Entity* theEntity = entities[ j ] ;
00057                 entities[ j ]->SetFrameManager( &theFrameManager ) ;
00058                 success &= AddEntityToSwiftScene( entities[ j ] ) ;
00059         }
00060         CD_Bool::allGeometryUsed = success ;    //this tells us if all the geometry was used in the collision detector
00061     
00062     //unfortunately, it appears we need to call these here, as well as in the CD_BasicStyle constructor
00063     PermActivateAll() ;                     // CD_BasicStyle only
00064         PermDeactivateFramesWithThemselves() ;  // CD_BasicStyle only
00065 
00066     // deactivate objects within the same frame
00067     std::vector< LinkBase* > links = universe.GetAllLinks();
00068     int i;
00069     int size = links.size();
00070     for( i = 0; i < size; i++ )
00071     {
00072         LinkBase* link = links[ i ];
00073         //** why is this here?  int baseframe = link->BaseFrameNum();
00074         int controlledSize = link->controlledFrames.size();
00075 
00076         for(int j = 0; j < controlledSize; j++)
00077         {
00078             int controlledFrame = link->controlledFrames[ j ];
00079             DeactivateFrames( controlledFrame, controlledFrame );
00080         }
00081     }
00082 
00083         // deactivate frames with their parents
00084     for( i = 0; i < size; i++ )
00085     {
00086         LinkBase* link = links[ i ];
00087         int baseframe = link->BaseFrameNum();
00088 
00089         int j;
00090         int controlledSize = link->controlledFrames.size();
00091         for( j = 0; j < controlledSize; j++ )
00092         {
00093             int controlledFrame = link->controlledFrames[ j ];
00094             DeactivateFrames( baseframe, controlledFrame );
00095         }
00096     }
00097 }
00098 
00099 CD_Swiftpp::CD_Swiftpp (const CD_Swiftpp& right)
00100     : m_pUniversePointer(NULL),
00101     CollisionDetectorBase( right ),
00102         CD_BasicStyle( right ),
00103         CD_Linear( right ),
00104         CD_LinearContinuous( right )
00105 {
00106         //the entities will be recopied later on - the ones copied in CD_BasicStyle are deleted
00107         m_pSwiftScene = new SWIFT_Scene;
00108         
00109         m_vMeshes.reserve( right.m_vMeshes.size() ) ;
00110         for( int i = 0; i < right.m_vMeshes.size(); i++ )
00111         {
00112                 int numMeshes = m_vMeshes.size() ;
00113                 Mesh* addMe = right.m_vMeshes[ i ] ; 
00114                 this->AddEntityToSwiftScene( addMe ) ;
00115         }
00116 }
00117 
00118 CD_Swiftpp::~CD_Swiftpp()
00119 {
00120     int i;
00121         for( i = 0; i < m_vMeshes.size(); i++ )
00122         {
00123                 Mesh* deleteMe = m_vMeshes[ i ] ;
00124                 delete deleteMe ;
00125                 m_vMeshes[ i ] = NULL ;
00126         }
00127         m_vMeshes.clear() ;
00128 
00129         for( i = 0; i < m_vSwiftppIndexes.size(); i++ )
00130         {
00131                 m_pSwiftScene->Delete_Object( m_vSwiftppIndexes[ i ] ) ;
00132         }
00133         m_vSwiftppIndexes.clear() ;
00134         for( i = 0; i < m_vLinkSwiftpp.size(); i++ )
00135         {
00136                 m_vLinkSwiftpp[ i ].clear() ;
00137         }
00138         m_vLinkSwiftpp.clear() ;
00139 
00140         delete m_pSwiftScene ;
00141 }
00142 
00143 CollisionDetectorBase* CD_Swiftpp::Clone () const
00144 {
00145     CD_Swiftpp* newSP = new CD_Swiftpp( *this ) ;
00146         CD_InterfaceToCollisionQueries* CDitc = dynamic_cast< CD_Bool* >( newSP ) ;
00147         CollisionDetectorBase* returnMe = dynamic_cast< CollisionDetectorBase* >( CDitc );
00148         return returnMe ;
00149 }
00150  
00151 bool CD_Swiftpp::AddEntityToSwiftScene(const Entity* entity)
00152 {
00153     int baseFrame = entity->BaseFrame() ;
00154         while( m_vLinkSwiftpp.size() < baseFrame + 1 )     
00155         {
00156                 std::set< unsigned int > setOfSwiftppMeshes ;
00157                 m_vLinkSwiftpp.push_back( setOfSwiftppMeshes );
00158         }
00159 
00160         const Mesh* mesh = dynamic_cast< const Mesh* >( entity ) ;
00161         if( mesh != NULL )
00162         {
00163                 int SwiftppIndex = AddMeshToSwiftScene( *mesh, (baseFrame == 0)) ;  
00164                 // if entity is in baseFrame 0, then it is fixed (obstacle); else moving
00165         if (SwiftppIndex != -1) {return true ;}     
00166         else {return false;}
00167         }
00168         const ObjectGroup* group = dynamic_cast< const ObjectGroup* >( entity ) ;
00169         if( group != NULL )
00170         {
00171                 bool returnMe = true ;
00172                 for( int i = 0; i < group->Size(); i++ )
00173                 {
00174                         const ObjectBase* addme = ( *group )[ i ] ;
00175                         returnMe &= AddEntityToSwiftScene( addme ) ;
00176                 }
00177                 return returnMe ;
00178         }
00179 
00180     const R_OpenChain* pRobot = dynamic_cast<R_OpenChain*>(entity->Clone());
00181     if (pRobot != NULL)
00182     {              
00183         return true;
00184     }
00185 
00186         const Range_Sensor* camera = dynamic_cast< const Range_Sensor* >( entity ) ;
00187         if( camera != NULL )
00188         {
00189                 //cameras don't need to be added to the simple version of m_pSwiftScene, only meshes
00190                 return true ;
00191         }
00192 
00193         return false ;
00194 }
00195 
00196 int CD_Swiftpp::AddMeshToSwiftScene(const Mesh& mesh, const bool bFixed)
00197 // even though writing to a .poly file, decomposing to a hierarchy file and then 
00198 // adding it to the scene seems to be a lot more work than just using 
00199 // Add_Convex_Object, this method will give greater flexibility in the meshes 
00200 // allowed to be added to the scene (non-triangular faces, non-convex objects), 
00201 // thus minimizing the amount of code changed in the future (hopefully!).
00202 {
00203 /*
00204 1) create a new .poly file -> "object1.poly"
00205 2) fwrite POLY on first line
00206 3) fwrite number of points
00207 4) fwrite number of faces
00208 5) go through all the vertices' xyz's, fwrite them
00209 6a) note the number of vertices making up the face
00210 6b) go through the mesh/entity's faces' vertexNumbers
00211 7) save file
00212 8) decompose file - this allows the original shape to be non-convex
00213 9) add object to the scene
00214 10) push the object id into the vector in the same order as the mesh is stored
00215 */
00216 
00217         Mesh* addMe = dynamic_cast< Mesh*>( mesh.Clone() ) ;
00218     if (addMe == NULL)
00219     {
00220         return -1;
00221     }
00222         m_vMeshes.push_back( addMe ) ;
00223 
00224         int nObjectId = -1;     
00225 
00226     char sFileName[MAX_FILENAME_LENGTH], 
00227          sPolyFileName[MAX_FILENAME_LENGTH],
00228                  sHierFileName[MAX_FILENAME_LENGTH],
00229                  sCurDir[MAX_FILENAME_LENGTH];
00230          
00231         if (_getcwd(sCurDir, MAX_FILENAME_LENGTH) == NULL)
00232         {
00233                 return nObjectId;
00234         }
00235     
00236         sprintf(sFileName, "%s\\%s", sCurDir, FILENAME);
00237         int length = sprintf(sPolyFileName, "%s%s", sFileName, POLYEXT);
00238     if (length < MIN_FILENAME_LENGTH)   // sprintf didn't concat properly
00239     {
00240         return nObjectId;
00241     }
00242 
00243     FILE* pFile = fopen(sPolyFileName, "w");
00244     if (pFile == NULL)
00245     {
00246         return nObjectId;
00247     }
00248 
00249     int nWritten = fwrite(POLY, sizeof(char), sizeof(POLY)-1, pFile);
00250     if (nWritten < (sizeof(POLY)-1))
00251     {
00252         assert(fflush(pFile) == 0);
00253         assert(fclose(pFile) == 0);
00254         return nObjectId;
00255     }
00256 
00257     int nVertices = addMe->vertexes.size();
00258     int nFaces = addMe->facets.size();
00259 
00260     length = fprintf(pFile, "%d\n\n%d\n\n", nVertices, nFaces);
00261     if (length < 6)         // minimum of 6 characters written
00262     {
00263         assert(fflush(pFile) == 0);
00264         assert(fclose(pFile) == 0);
00265         return nObjectId;
00266     }
00267     
00268     // write vertices info
00269     for (int i = 0; i < nVertices; i++)
00270     {
00271         length = fprintf(pFile, "%f %f %f\n", 
00272             (addMe->vertexes)[i][0],
00273             (addMe->vertexes)[i][1],
00274             (addMe->vertexes)[i][2]);
00275         if (length < 5)     // minimum of 5 characters written
00276         {
00277             assert(fflush(pFile) == 0);
00278             assert(fclose(pFile) == 0);
00279             return nObjectId;
00280         }
00281     }
00282 
00283     // write face info
00284     int vn;
00285     for (i = 0; i < nFaces; i++)
00286     {
00287         vn = (addMe->facets)[i].vertexNumbers.size();
00288         length = fprintf(pFile, "\n%d ", vn);
00289         for (int j = 0; j < vn; j++)
00290         {
00291             length += fprintf(pFile, "%d ", (addMe->facets)[i].vertexNumbers[j]);            
00292         }
00293 
00294         if (length < 7)
00295         {
00296             assert(fflush(pFile) == 0);
00297             assert(fclose(pFile) == 0);
00298             return nObjectId;
00299         }
00300     }  
00301 
00302     // done writing .poly file so close it
00303     assert(fflush(pFile) == 0);
00304     assert(fclose(pFile) == 0);
00305 
00306     // decompose file
00307     sprintf( sHierFileName, "%s%s", sFileName, HIEREXT);
00308     
00309     hier_filename = new char[strlen(sHierFileName)+1];
00310         strcpy(hier_filename, sHierFileName);
00311 
00312     SWIFT_Scene scene;
00313     
00314     if (Gui_Init_Before_TclTk(sPolyFileName) == false) 
00315     {return nObjectId;}
00316 
00317         // make sure the hierarchy file is newer than the poly file 
00318         struct _stat bufPoly, bufHier;
00319     int result = _stat(sPolyFileName, &bufPoly);
00320     if (result != 0){return nObjectId;}
00321     result = _stat(sHierFileName, &bufHier);
00322     if (result != 0){return nObjectId;}
00323     // .poly file has later time stamp
00324     if (bufPoly.st_mtime > bufHier.st_mtime){return nObjectId;}  
00325         
00326     // add hierarchy file to scene
00327     if( m_pSwiftScene->Add_General_Object( sHierFileName, nObjectId, bFixed,
00328                         DEFAULT_ORIENTATION, DEFAULT_TRANSLATION, DEFAULT_SCALE, 
00329                         DEFAULT_SPLIT_TYPE, BOX_SETTING_CHOOSE, 
00330                         DEFAULT_BOX_ENLARGE_REL, m_dObsTol) == false) 
00331     {
00332         return -1;
00333     } 
00334     
00335         //need to update the list of baseframe - mesh references
00336     int baseFrame = mesh.BaseFrame() ;
00337         std::set< unsigned int > theSet = m_vLinkSwiftpp[ baseFrame ] ;
00338         theSet.insert( nObjectId ) ;
00339         m_vLinkSwiftpp[ baseFrame ] = theSet ;  
00340         
00341         m_vSwiftppIndexes.push_back(nObjectId) ;
00342 
00343         return nObjectId;
00344 
00345 }
00346 
00347 void CD_Swiftpp::DeactivateFrames (const unsigned int frame1, const int frame2)
00348 {
00349     if( frame2 > frame1 )
00350         {
00351                 DeactivateFrames( frame2, frame1 ) ;
00352                 return ;
00353         }
00354         if (frame2 != -1)
00355         {
00356                 CD_BasicStyle::DeactivateFrames( frame1, frame2 ) ;     
00357         }
00358         int lSize = m_vLinkSwiftpp.size() ;
00359 
00360         //if we're deactivating a frame with no geometry, just return
00361         if( lSize <= frame1 )
00362         {
00363                 return ;
00364         }
00365         if( lSize <= frame2 )
00366         {
00367                 return ;
00368         }
00369 
00370         std::set< unsigned int >::iterator i1 ;
00371         std::set< unsigned int >::iterator i2 ;
00372 
00373         for( i1 = m_vLinkSwiftpp[ frame1 ].begin(); i1 != m_vLinkSwiftpp[ frame1 ].end() ; i1++ )
00374         {
00375                 int index1 = *i1 ;
00376         if (frame2 == -1)
00377         {
00378             m_pSwiftScene->Deactivate(index1);
00379         }
00380         else
00381         {
00382                     for( i2 = m_vLinkSwiftpp[ frame2 ].begin(); i2 != m_vLinkSwiftpp[ frame2 ].end(); i2++ )
00383                     {
00384                             int index2 = *i2 ;
00385                             if( index1 != index2 )
00386                             {
00387                                     m_pSwiftScene->Deactivate( index1, index2 ) ;
00388                                     m_pSwiftScene->Deactivate( index2, index1 ) ;                               
00389                             }
00390                     }
00391         }
00392         }
00393 }
00394 
00395 
00396 void CD_Swiftpp::ActivateFrames (const unsigned int frame1, const int frame2)
00397 {
00398     if( !FramePairPermEnabled( frame1, frame2 ) )       //IMPROVE: NOT SIGN?
00399         {
00400                 return ;        //if the pair is permanantly disabled, then don't activate it
00401         }
00402 
00403         if( frame2 > frame1 )
00404         {
00405                 ActivateFrames( frame2, frame1 ) ;
00406                 return ;
00407         }
00408 
00409         if (frame2 != -1)
00410         {
00411                 CD_BasicStyle::ActivateFrames( frame1, frame2 ) ;
00412         }
00413         int lSize = m_vLinkSwiftpp.size() ;
00414 
00415         //if we're activating a frame with no geometry, just return
00416         if( lSize <= frame1 )
00417         {
00418                 return ;
00419         }
00420         if( lSize <= frame2 )
00421         {
00422                 return ;
00423         }
00424 
00425         std::set< unsigned int >::iterator i1 ;
00426         std::set< unsigned int >::iterator i2 ;
00427 
00428         for( i1 = m_vLinkSwiftpp[ frame1 ].begin(); i1 != m_vLinkSwiftpp[ frame1 ].end() ; i1++ )
00429         {
00430                 int index1 = *i1 ;
00431         if (frame2 == -1)
00432         {
00433             m_pSwiftScene->Activate(index1);
00434         }
00435         else
00436         {
00437                     for( i2 = m_vLinkSwiftpp[ frame2 ].begin(); i2 != m_vLinkSwiftpp[ frame2 ].end(); i2++ )
00438                     {
00439                             int index2 = *i2 ;
00440                             if( index1 != index2 )
00441                             {
00442                                     m_pSwiftScene->Activate( index1, index2 ) ;
00443                                     m_pSwiftScene->Activate( index2, index1 ) ;
00444                             }
00445                     }
00446         }
00447         }
00448 }
00449 
00450 /*
00451 bool CD_Swiftpp::QueryIntersection(bool bEarlyExit, int& num_pairs, int** oids)
00452 {
00453     bool bReturn;
00454     return bReturn;
00455 }*/
00456 
00457 bool CD_Swiftpp::QueryContactDetermination(const Configuration& config, bool bEarlyExit, 
00458     SWIFT_Real tolerance, int& num_pairs, int** oids, int** num_contacts, 
00459     SWIFT_Real** distances,  SWIFT_Real** nearest_pts, SWIFT_Real** normals)
00460 {
00461     
00462         CD_Bool::IncrementCallCount();
00463 
00464     Semaphore semaphore( this->guid );
00465         semaphore.Lock();
00466         SetConfiguration( config ) ;
00467 
00468     // go through all the links and look at the meshes that are there to update their frames
00469     // SWIFT++ uses an array of size 12 to represent the R and T of transform matrix (row major).
00470     double RT[12];
00471     int nObjectId; 
00472         for( int i = 0; i < m_vMeshes.size(); i++ )
00473         {
00474                 const Mesh* mesh = m_vMeshes[ i ] ;
00475 
00476                 Matrix4x4 m1 = mesh->GetTransform(); 
00477 
00478         for (int j = 0; j < 3; j++)
00479         {
00480             for (int k = 0; k < 4; k++)
00481             {
00482                 RT[4*j+k] = m1(j,k);
00483             }
00484         }
00485 
00486         nObjectId = m_vSwiftppIndexes[i];
00487                 assert( nObjectId >= 0 ) ;
00488 
00489                 m_pSwiftScene->Set_Object_Transformation(nObjectId, RT);
00490         }
00491 
00492     bool bIntersect = m_pSwiftScene->Query_Intersection(bEarlyExit, num_pairs, oids);
00493     
00494     if ((bEarlyExit != false) && (bIntersect != false))     
00495         // user only wants to know if there's an intersection
00496     {
00497         semaphore.Unlock();
00498         return true;
00499     }
00500     
00501     bIntersect = m_pSwiftScene->Query_Contact_Determination(bEarlyExit, tolerance, 
00502         num_pairs, oids, num_contacts, distances, nearest_pts, normals);
00503     
00504     semaphore.Unlock();
00505     return bIntersect;
00506 }
00507 
00508 bool CD_Swiftpp::IsInterfering (const Configuration& config)
00509 {
00510     int np, *oids;
00511     
00512     CD_Bool::IncrementCallCount();
00513 
00514     Semaphore semaphore( this->guid );
00515         semaphore.Lock();
00516         SetConfiguration( config ) ;
00517 
00518     // go through all the links and look at the meshes that are there to update their frames
00519     // SWIFT++ uses an array of size 12 to represent the R and T of transform matrix (row major).
00520     double RT[12];
00521     int nObjectId;     
00522     Matrix4x4 m1;
00523         for( int i = 0; i < m_vMeshes.size(); i++ )
00524         {
00525                 const Mesh* mesh = m_vMeshes[ i ] ;
00526 
00527                 m1 = mesh->GetTransform(); 
00528 
00529         for (int j = 0; j < 3; j++)
00530         {
00531             for (int k = 0; k < 4; k++)
00532             {
00533                 RT[4*j+k] = m1(j,k);
00534             }
00535         }
00536 
00537         nObjectId = m_vSwiftppIndexes[i];
00538                 assert( nObjectId >= 0 ) ;
00539 
00540                 m_pSwiftScene->Set_Object_Transformation(nObjectId, RT);
00541         }
00542 
00543     bool bIntersect = m_pSwiftScene->Query_Tolerance_Verification(true, m_dObsTol, np, &oids);
00544     
00545     semaphore.Unlock();
00546 
00547     return bIntersect;
00548 }
00549 
00550 int CD_Swiftpp::GetRobotLinkBaseFrame(int objectId)
00551 {
00552     std::set< unsigned int >::iterator it = m_vLinkSwiftpp[0].begin();
00553     for (int i = 0; i < m_vLinkSwiftpp.size(); i++)
00554     {
00555         it = m_vLinkSwiftpp[i].find(objectId);
00556         if (it != m_vLinkSwiftpp[i].end())
00557         {
00558             return i;
00559         }
00560     }    
00561     return -1;
00562 }

Generated on Sat Apr 1 21:30:37 2006 for Motion Planning Kernel by  doxygen 1.4.6-NO