planners/inversekin/IK_InvKinBase.cpp

Go to the documentation of this file.
00001 //=========================================================================
00002 //
00003 //  File:  IK_InvKinBase.cpp
00004 //
00005 //  Created 07-Feb-01 by Shane Schneider
00006 //
00007 //              Planner Base for planners requiring a graph data structure
00008 //              Contains the actual graph structure as well as several draw and
00009 //              computation functions.
00010 
00011 
00012 
00013 // IK_InvKinBase
00014 #include "synchronization/semaphore.h"
00015 #include "planners/InverseKin/IK_InvKinBase.h"
00016 #include "robots/R_OpenChain.h"
00017 
00018 #include <assert.h>
00019 #include <math.h>
00020 #include <math/math2.h>
00021 #include <iosfwd>
00022 #include <iostream>
00023 #include <opengl/gl_Frame.h>
00024 
00025 // fix gl path...
00026 // #include <gl/glos.h>
00027 #ifndef NOGL
00028     #include "opengl/glos.h"
00029     #include <gl/gl.h>
00030 #endif
00031 
00032 using std::endl;
00033 
00034 //--------------------- Constants ---------------
00035 static const int FRAMEDOF = 6;
00036 
00037 // Class IK_InvKinBase 
00038 
00039 // Default Constructor
00040 IK_InvKinBase::IK_InvKinBase()
00041 :
00042         m_GoalFrameIndex( -1 )
00043 {
00044 }
00045 
00046 
00047 IK_InvKinBase::~IK_InvKinBase()
00048 {
00049         // Default Destructor
00050 }
00051 
00052 
00053 //=============================================================================
00054 // DrawExplicit
00055 //
00056 // Purpose: Draws the planner data to the planner window when called
00057 //=============================================================================
00058 bool IK_InvKinBase::DrawExplicit () const
00059 {
00060 
00061         return false;
00062 }
00063 
00064 //=============================================================================
00065 // DrawExplicit
00066 //
00067 // Purpose: Draws the planner data to the planner window when called
00068 //=============================================================================
00069 void IK_InvKinBase::DrawUniversePortion() const
00070 {
00071 #ifndef NOGL
00072         GL_Frame glFrame( goalFrame );
00073         ::glPushMatrix();
00074         glFrame.GLDraw();
00075         ::glPopMatrix();
00076 #endif
00077 }
00078 
00079 
00080 //=============================================================================
00081 // Load
00082 //
00083 // Purpose: Loads partailly complete planner data from the disk
00084 //=============================================================================
00085 bool IK_InvKinBase::Load (const char *filename)
00086 {
00087         Semaphore semaphore( this->guid );
00088         semaphore.Lock();
00089         
00090         // Add file loading code here...
00091 
00092         // IMPROVE:  This class and all derived classes will need to save the goal frame
00093         
00094         semaphore.Unlock();
00095         return true;
00096 }
00097 
00098 
00099 //=============================================================================
00100 // Does Planning
00101 //
00102 // Purpose: performs the planning task
00103 //=============================================================================
00104 bool IK_InvKinBase::Plan ()
00105 {
00106         assert( false );                //this is an abstract base class, and should never be called
00107         return false;
00108 }
00109 
00110 //=============================================================================
00111 // Save
00112 //
00113 // Purpose: Saves partial plan data to disk
00114 //=============================================================================
00115 bool IK_InvKinBase::Save (const char *filename) const
00116 {
00117         Semaphore semaphore( this->guid );
00118         semaphore.Lock();
00119 
00120         // Add file saving data here...
00121 
00122         // IMPROVE:  This class and all derived classes will need to save the goal frame
00123 
00124         semaphore.Unlock();
00125         return true;
00126 }
00127 
00128 //=============================================================================
00129 // SetStartConfig
00130 //
00131 // Purpose: Sets the start config.
00132 //
00133 //=============================================================================
00134 /*void IK_InvKinBase::SetStartConfig( const Configuration& config )
00135 {
00136         // Call the parent SetStartConfig to ensure all required initialization is established.
00137         PL_Boolean_Output::SetStartConfig( config );
00138 
00139 }
00140 */
00141 //=============================================================================
00142 // SetGoalConfig
00143 //
00144 // Purpose: Overloads the SetGoalConfig of normal planners and prevents
00145 //                      a goal configuration from being assigned since the IK planner
00146 //                      uses a goal frame and not a goal configuration.  Once the 
00147 //                      the IK planner has computed a configuration and path to the goal frame,
00148 //                      the AssignGoalConfig is called which saves the computed configuration
00149 //                      as the goal configuration.
00150 //
00151 //=============================================================================
00152 /*void IK_InvKinBase::SetGoalConfig( const Configuration& config )
00153 {
00154 
00155         // does nothing!
00156 
00157         //IMPROVE:  Remove call to parent's assign goal config
00158         PL_Boolean_Output::SetGoalConfig( config );
00159 
00160         
00161         return;
00162 
00163 } */
00164 
00165 //=============================================================================
00166 // CopySettings
00167 //
00168 // Purpose: copies the settings from a different planner
00169 //=============================================================================
00170 void IK_InvKinBase::CopySettings( PlannerBase* original )
00171 {
00172         IK_InvKinBase* originalIKBase = dynamic_cast< IK_InvKinBase* >( original );
00173         if( originalIKBase == NULL )
00174         {
00175                 return;
00176         }
00177 
00178         this->goalFrame = originalIKBase->goalFrame;
00179 }
00180 
00181 
00182 //=============================================================================
00183 // AssignGoalConfig
00184 //
00185 // Purpose: locally called function that assigns the computed goal configuration
00186 //                      for the solved goal frame in the server and the planner.
00187 //                      
00188 //                      This function is used after the planner has solved the IK planning
00189 //                      problem and computes a configuration that meets the goal frame.
00190 //                      This function then saves the computed configuration so other
00191 //                      planners can try to solve for the same configuration.
00192 //=============================================================================
00193 void IK_InvKinBase::AssignGoalConfig( const Configuration& config ) 
00194 {
00195         // Assign the goal config to the planner
00196         // Call the parent SetGoalConfig to ensure all required initialization is established.
00197         PL_Boolean_Output::SetGoalConfig( config );
00198 
00199         // IMPROVE:  Add code to set the goal config to the server.
00200 
00201 }
00202 
00203 
00204 //=============================================================================
00205 // SetGoalFrame
00206 //
00207 // Purpose: Assign the desired goal frame to solve for.
00208 //
00209 // NOTE:    This is the function that should be eventually called by all
00210 //                      overloaded versions of the function.  It is used to assign and set
00211 //                      any other parameters required when setting the goal frame.
00212 //=============================================================================
00213 void IK_InvKinBase::SetGoalFrame( const Matrix4x4& newFrame )
00214 {
00215         if ( goalFrame != newFrame )
00216         {
00217                 goalFrame = newFrame;
00218 
00219                 // Initialize a new search.
00220                 this->InitNewSearch();
00221         }
00222 }
00223 
00224 //=============================================================================
00225 // SetGoalFrame
00226 //
00227 // Purpose: Assign the desired goal frame to solve for based on the tool frame
00228 //                      generated by the given configuration.
00229 //=============================================================================
00230 void IK_InvKinBase::SetGoalFrame( const Configuration& config )
00231 {
00232         // find the tool frame from the given configuration
00233         Matrix4x4 tempFrame = GetToolFrame( config );
00234 
00235         // assign the goal frame
00236         SetGoalFrame( tempFrame );
00237 }
00238 
00239 //=============================================================================
00240 // SetGoalFrame
00241 //
00242 // Purpose: Assign the desired goal frame to solve for based on DOF vector given
00243 //=============================================================================
00244 void IK_InvKinBase::SetGoalFrame( const VectorN& dofVector )
00245 {
00246         // verify the vector has the correct number of components.
00247         assert( dofVector.Length() == FRAMEDOF );
00248 
00249         // assign the goal frame
00250         SetGoalFrame( dofVector[0], dofVector[1], dofVector[2], 
00251                           dofVector[3], dofVector[4], dofVector[5] ); 
00252 
00253 }
00254 
00255 //=============================================================================
00256 // SetGoalFrame
00257 //
00258 // Purpose: Assign the desired goal frame to solve for based on fixed angle
00259 //                  X-Y-Z rotation and translated accordingly.
00260 //      
00261 // Note:    Roll, Pitch, and Yaw are to be expressed in degrees.
00262 //=============================================================================
00263 void IK_InvKinBase::SetGoalFrame( const double& x, const double& y, const double& z, 
00264                                                                   const double& roll, const double& pitch, const double& yaw )
00265 {
00266         Matrix4x4 newFrame = GetTransformFrame( x, y, z, roll, pitch, yaw );
00267 
00268         // Assign the generated frame as the new goal frame
00269         SetGoalFrame( newFrame );
00270 }
00271 
00272 //=============================================================================
00273 // GetTransformFrame
00274 //
00275 // Purpose: Calculate a frame transformation based on fixed angle
00276 //                  X-Y-Z rotation and translated accordingly wrt to the world frame.
00277 //                      The parameters are passed as a VectorN of size FRAMEDOF.
00278 //                      The resulting frame can then be used as the desired goal frame.
00279 //      
00280 // Note:    Roll, Pitch, and Yaw are to be expressed in degrees.
00281 //=============================================================================
00282 Matrix4x4 IK_InvKinBase::GetTransformFrame( const VectorN& dofVector ) const
00283 {
00284         // verify the vector has the correct number of components.
00285         assert( dofVector.Length() == FRAMEDOF );
00286 
00287         // get the frame transformation
00288         Matrix4x4 newFrame = GetTransformFrame( dofVector[0], dofVector[1], dofVector[2], 
00289                                                     dofVector[3], dofVector[4], dofVector[5] ); 
00290 
00291         return newFrame;
00292 }
00293 
00294 //=============================================================================
00295 // GetTransformFrame
00296 //
00297 // Purpose: Calculate a frame transformation based on fixed angle
00298 //                  X-Y-Z rotation and translated accordingly wrt to the world frame.
00299 //                      The resulting frame can then be used as the desired goal frame.
00300 //      
00301 // Note:    Roll, Pitch, and Yaw are to be expressed in degrees.
00302 //=============================================================================
00303 Matrix4x4 IK_InvKinBase::GetTransformFrame( const double& x, const double& y, const double& z, 
00304                                                                                     const double& roll, const double& pitch, const double& yaw )
00305 {
00306         // translate angles from degress to radians.
00307         double alpha = Deg2Rad( yaw );
00308         double beta  = Deg2Rad( pitch );
00309         double gamma = Deg2Rad( roll );
00310 
00311         // Cache trig values for quicker multiplcation.
00312         double cA = cos( alpha );
00313         double sA = sin( alpha );
00314         double cB = cos( beta );
00315         double sB = sin( beta );
00316         double cY = cos( gamma );
00317         double sY = sin( gamma );
00318 
00319         // Generate frame based on translation and fixed angle rotation
00320         Matrix4x4 newFrame;
00321         newFrame( 0 , 0 ) = cA*cB;
00322         newFrame( 1 , 0 ) = sA*cB;
00323         newFrame( 2 , 0 ) = -sB;
00324         newFrame( 3 , 0 ) = 0;
00325 
00326         newFrame( 0 , 1 ) = cA*sB*sY - sA*cY;
00327         newFrame( 1 , 1 ) = sA*sB*sY + cA*cY;
00328         newFrame( 2 , 1 ) = cB*sY;
00329         newFrame( 3 , 1 ) = 0;
00330 
00331         newFrame( 0 , 2 ) = cA*sB*cY + sA*sY;
00332         newFrame( 1 , 2 ) = sA*sB*cY - cA*sY;
00333         newFrame( 2 , 2 ) = cB*cY;
00334         newFrame( 3 , 2 ) = 0;
00335 
00336         newFrame( 0 , 3 ) = x;
00337         newFrame( 1 , 3 ) = y;
00338         newFrame( 2 , 3 ) = z;
00339         newFrame( 3 , 3 ) = 1;
00340 
00341         // return resulting new frame
00342         return newFrame;
00343 
00344 }
00345 
00346 //=============================================================================
00347 // GetRotAngles
00348 //
00349 // Purpose: Calculates the fixed rotation angles and translation for the given
00350 //                  frame wrt to the world frame.  The results are passed by reference.
00351 //      
00352 // Note:    Roll, Pitch, and Yaw are expressed in degrees.
00353 //=============================================================================
00354 void IK_InvKinBase::GetRotAngles( const Matrix4x4& frame, double& x, double& y, double& z,
00355                                                                   double& roll, double& pitch, double& yaw ) const
00356 {
00357         // Declare the fixed angle variables.
00358         double alpha, beta, gamma;
00359         
00360 
00361         // Calculate beta and cache the cosine.
00362         beta = atan2( -frame(2,0) , sqrt( Sqr(frame(0,0)) + Sqr(frame(1,0)) ) );
00363         double cB = cos ( beta );
00364 
00365         // Calculate the other two rotations
00366         if ( cB == 0.0 )
00367         { 
00368                 alpha = 0;
00369                 if ( beta > 0 ) // if beta == PI/2
00370                 {
00371                         gamma = atan2( frame(0,1) , frame(1,1) );
00372                 }
00373                 else
00374                 {
00375                         gamma = -atan2( frame(0,1), frame(1,1) );
00376                 }
00377         }
00378         else
00379         {
00380                 alpha = atan2( frame(1,0) / cB , frame(0,0) / cB );
00381                 gamma = atan2( frame(2,1) / cB , frame(2,2) / cB );
00382         }
00383 
00384         // Convert angles to degrees and assign to appropriate parameters
00385         // NOTE:  These angles must correspond to same angles used in SetGoalFrame
00386         yaw   = Rad2Deg( alpha );
00387         pitch = Rad2Deg( beta );
00388         roll  = Rad2Deg( gamma );
00389 
00390         // Get the translations
00391         x = frame(0,3);
00392         y = frame(1,3);
00393         z = frame(2,3);
00394 }
00395 
00396 //=============================================================================
00397 // GetRotVector
00398 //
00399 // Purpose: Calculates the fixed rotation angles and translation for the given
00400 //                  frame wrt to the world frame, and returns the result as a vector of
00401 //                      size FRAMEDOF.
00402 //      
00403 // Note:    Roll, Pitch, and Yaw are expressed in degrees.
00404 //=============================================================================
00405 VectorN IK_InvKinBase::GetRotVector( const Matrix4x4& frame ) const
00406 {
00407         // create Vector
00408         VectorN returnMe;
00409         returnMe.SetLength( FRAMEDOF );
00410 
00411         // assign the values
00412         GetRotAngles( frame, returnMe[0], returnMe[1], returnMe[2], returnMe[3], returnMe[4], returnMe[5] );
00413 
00414         // return the vector
00415         return returnMe;
00416 }
00417 
00418 //=============================================================================
00419 // GetGoalFrame
00420 //
00421 // Purpose: Returns the goal frame that the IK planner will attempt to solve for
00422 //
00423 //=============================================================================
00424 Matrix4x4 IK_InvKinBase::GetGoalFrame() const
00425 {
00426         return goalFrame;
00427 }
00428 
00429 //=============================================================================
00430 // GetGoalFrame
00431 //
00432 // Purpose: Returns the goal frame that the IK planner will attempt to solve for
00433 //                      as a 6-dof of vector, with each component representing the translation
00434 //                  or fixed angle rotation about the axis
00435 //
00436 //=============================================================================
00437 VectorN IK_InvKinBase::GetGoalFrameVector() const
00438 {
00439         VectorN returnMe;
00440         returnMe.SetLength( FRAMEDOF );
00441         
00442         GetRotAngles( goalFrame, returnMe[0], returnMe[1], returnMe[2], returnMe[3], returnMe[4], returnMe[5] );
00443 
00444         return returnMe;
00445 }
00446 
00447 //=============================================================================
00448 // GetToolFrame
00449 //
00450 // Purpose: Computes the tool frame for the robot for a given configuration wrt world frame.
00451 //
00452 // Note:    This function will move the robot to the given configuration and
00453 //                      force an update of all frames.  This function should not
00454 //                      be called too often.
00455 //=============================================================================
00456 Matrix4x4 IK_InvKinBase::GetToolFrame( const Configuration& config ) const
00457 {
00458 #if 0
00459         if ( collisionDetector == NULL )
00460         {
00461                 return Matrix4x4();
00462         }
00463 
00464         // get pointer to frame manager
00465         FrameManager* frameManager = collisionDetector->GetFrameManager();
00466 
00467         // move the robot to desired config
00468         collisionDetector->SetConfiguration( config );
00469 
00470         // IMPROVE:  temporary method of finding the tool frame in frame manager
00471         int toolFrameNum = 0;
00472         if ( config.DOF() > 0 )
00473         {
00474                 toolFrameNum = collisionDetector->JointFrameNum( config.DOF() - 1 );
00475         }
00476                 
00477         Matrix4x4 toolFrame = frameManager->GetWorldFrame( toolFrameNum );
00478 #else
00479         Frame toolFrame = Matrix4x4();
00480 
00481         if ( collisionDetector != NULL )
00482         {
00483                 FrameManager* frameManager = collisionDetector->GetFrameManager();
00484                 collisionDetector->SetConfiguration( config );
00485                 //toolFrame = frameManager->GetWorldFrame( m_toolFrame );
00486                 R_OpenChain * robot = (R_OpenChain *)collisionDetector->GetRobot(0);
00487                 int toolFrameID = robot->GetToolFrame(0);
00488                 if (toolFrameID == -1)
00489                 {
00490                         toolFrameID = collisionDetector->JointFrameNum( config.DOF() - 1 );
00491                         toolFrame = frameManager->GetWorldFrame( toolFrameID );
00492                 }
00493                 else
00494                 {
00495                         toolFrame = *(frameManager->GetFrameRef(toolFrameID));
00496                         toolFrame = frameManager->GetTransformRelative(collisionDetector->DOF(), 0) * toolFrame;
00497                 }
00498         }
00499 
00500 #endif
00501         return toolFrame;
00502 }
00503 
00504 
00505 //=============================================================================
00506 // InitNewSearch
00507 //
00508 // Purpose: Abstract function that initiates parameters in derived classes to 
00509 //          indicate if a new search has been requested.
00510 //=============================================================================
00511 void IK_InvKinBase::InitNewSearch()
00512 {
00513         // do nothing...this is an abstract class that should be defined in 
00514         // derived classes if needed.
00515 
00516         return;
00517 }
00518 
00519 

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