00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "synchronization/semaphore.h"
00014 #include "robots/R_OpenChain.h"
00015 #include "IK_ACA.h"
00016
00017 #include <assert.h>
00018 #include <math.h>
00019 #include <math/math2.h>
00020 #include <math/vector4.h>
00021 #include <math/matrix4x4.h>
00022 #include <iosfwd>
00023 #include <iostream>
00024 #include <limits.h>
00025
00026 #include "Kinematics/DH_Link.h"
00027
00028
00029
00030
00031 #ifndef NOGL
00032 #include "opengl/glos.h"
00033 #include <gl/gl.h>
00034 #endif
00035
00036 using std::endl;
00037
00038
00039
00040 static const char FILEEXT[] = ".ikaca";
00041 static const char FILEHEADER[] = "INVERSE_ACA_PLANNER";
00042
00043 static const Vector4 PX (1,0,0);
00044 static const Vector4 PY (0,1,0);
00045 static const Vector4 PZ (0,0,1);
00046 static const double INFINITY = LONG_MAX;
00047 static const double DEFAULT_TOL = 0.02;
00048 static const double DEFAULT_TOL1 = 0.005;
00049 static const int DEFAULT_EMBRYOS_PER_NODE = 3;
00050 static const double SAMPLING_TIME = 0.5;
00051
00052 #define _USE_ORIENTATION_
00053
00054
00055
00056 IK_ACA::IK_ACA()
00057 {
00058
00059 strcpy( fileext, FILEEXT );
00060 strcpy( fileheader, FILEHEADER );
00061
00062
00063 embryosPerLandmark = DEFAULT_EMBRYOS_PER_NODE;
00064
00065
00066 embryo = new node_map<Configuration>[embryosPerLandmark];
00067 assert( embryo != NULL );
00068
00069 for ( int i = 0; i < embryosPerLandmark; i++ )
00070 {
00071 embryo[i].init(G);
00072 }
00073
00074
00075 searchPath.clear();
00076
00077
00078 searchLandmark = nil;
00079
00080
00081 InitBestParams();
00082 }
00083
00084
00085 IK_ACA::~IK_ACA()
00086 {
00087
00088 if ( embryo != NULL )
00089 {
00090 delete [] embryo;
00091 embryo = NULL;
00092 }
00093 }
00094
00095
00096
00097
00098
00099
00100 bool IK_ACA::DrawExplicit () const
00101 {
00102
00103 return PL_GraphBase::DrawExplicit();
00104 }
00105
00106
00107
00108
00109
00110
00111
00112 bool IK_ACA::Load (const char *filename)
00113 {
00114
00115 return PL_GraphBase::Load( filename );
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 bool IK_ACA::LoadContents( std::ifstream& infile )
00127 {
00128
00129 bool success = PL_GraphBase::LoadContents( infile );
00130 if ( !success )
00131 {
00132 return false;
00133 }
00134
00135
00136 VectorN goalFrameVector;
00137 infile >> goalFrameVector;
00138 SetGoalFrame( goalFrameVector );
00139
00140
00141
00142
00143
00144 infile >> embryosPerLandmark;
00145 if ( embryosPerLandmark < 1 )
00146 {
00147 embryosPerLandmark = 1;
00148 }
00149 if ( embryo != NULL )
00150 {
00151 delete [] embryo;
00152 }
00153 embryo = new node_map<Configuration>[embryosPerLandmark];
00154 assert( embryo != NULL );
00155 for ( int i = 0; i < embryosPerLandmark; i++ )
00156 {
00157 embryo[i].init(G);
00158 }
00159
00160
00161
00162 node n1;
00163 forall_nodes( n1, G )
00164 {
00165 int nodeID;
00166 infile >> nodeID;
00167 for( int i = 0; i < embryosPerLandmark; i++ )
00168 {
00169 infile >> embryo[i][n1];
00170 }
00171 }
00172
00173 InitNewSearch();
00174
00175 return true;
00176 }
00177
00178
00179
00180
00181
00182
00183
00184 bool IK_ACA::Plan ()
00185 {
00186
00187 if ( IsInterfering( GetStartConfig() ) )
00188 {
00189
00190 return false;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200 StartTimer();
00201
00202
00203 Semaphore semaphore( guid );
00204 if( this->m_UseSemaphores == true )
00205 {
00206 semaphore.Lock();
00207 }
00208
00209
00210 if ( ( goalNode != nil ) && ( goalNode != startNode ) )
00211 {
00212 G.del_node( goalNode );
00213 }
00214 goalNode = nil;
00215
00216
00217 ClearGraphPath();
00218
00219
00220 SuccessResultType success = FAIL;
00221
00222
00223 while ( true )
00224 {
00225
00226 if ( searchLandmark != nil )
00227 {
00228 semaphore.Unlock();
00229 success = Search( searchLandmark );
00230 semaphore.Lock();
00231 }
00232
00233 if ( success != FAIL )
00234 {
00235 break;
00236 }
00237
00238
00239 if (( searchLandmark != nil) && ( searchLandmark != G.last_node() ))
00240 {
00241
00242 searchLandmark = G.succ_node( searchLandmark );
00243 }
00244 else
00245 {
00246
00247 searchLandmark = Explore();
00248 }
00249
00250
00251 semaphore.Unlock();
00252 semaphore.Lock();
00253 }
00254
00255
00256 semaphore.Unlock();
00257 semaphore.Lock();
00258
00259 if ( success == PASS )
00260 {
00261
00262 ComputePath( searchLandmark, searchPath );
00263
00264
00265 bestPath.clear();
00266
00267
00268 semaphore.Unlock();
00269 return true;
00270 }
00271 else
00272 {
00273
00274
00275
00276
00277 searchPath.clear();
00278
00279
00280 semaphore.Unlock();
00281 return false;
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290 bool IK_ACA::Save (const char *filename) const
00291 {
00292
00293 return PL_GraphBase::Save( filename );
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 bool IK_ACA::SaveContents ( std::ofstream& outfile ) const
00305 {
00306
00307 bool success = PL_GraphBase::SaveContents( outfile );
00308 if ( !success )
00309 {
00310 return false;
00311 }
00312
00313
00314 outfile << GetGoalFrameVector() << endl;
00315
00316
00317
00318
00319 outfile << embryosPerLandmark << endl;
00320
00321
00322 node n1;
00323 forall_nodes( n1, G )
00324 {
00325 outfile << n1->id();
00326
00327 for( int i = 0; i < embryosPerLandmark; i++ )
00328 {
00329 outfile << embryo[i][n1];
00330 }
00331
00332 outfile << endl;
00333 }
00334
00335
00336 return true;
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 bool IK_ACA::DrawSpecific() const
00351 {
00352 node landmark;
00353 double Xcor, Ycor, Zcor;
00354
00355 #ifndef NOGL
00356
00357 glLineWidth( 1.0f );
00358 glBegin(GL_LINES);
00359
00360 glColor3f(0.4f,0.4f,0.4f);
00361 forall_nodes(landmark,G)
00362 {
00363 for( int i = 0; i < embryosPerLandmark; i++ )
00364 {
00365 GetCoords( embryo[i][landmark], Xcor, Ycor, Zcor );
00366 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00367
00368 GetCoords( landmark, Xcor, Ycor, Zcor );
00369 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00370 }
00371 }
00372
00373
00374 if ( !searchPath.empty() )
00375 {
00376 list_item index = searchPath.last();
00377 list_item first = searchPath.first();
00378 glColor3f(0.0f,1.0f,0.0f);
00379
00380 while ( first != index )
00381 {
00382 GetCoords( searchPath.inf( index ), Xcor, Ycor, Zcor );
00383 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00384
00385 index = searchPath.pred( index );
00386
00387 GetCoords( searchPath.inf( index ), Xcor, Ycor, Zcor );
00388 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00389 }
00390 }
00391
00392
00393 if ( !bestPath.empty() )
00394 {
00395 list_item index = bestPath.last();
00396 list_item first = bestPath.first();
00397 glColor3f(0.5f,0.0f,0.625f);
00398
00399 while ( first != index )
00400 {
00401 GetCoords( bestPath.inf( index ), Xcor, Ycor, Zcor );
00402 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00403
00404 index = bestPath.pred( index );
00405
00406 GetCoords( bestPath.inf( index ), Xcor, Ycor, Zcor );
00407 glVertex3f( (float)Xcor, (float)Ycor, (float)Zcor );
00408 }
00409 }
00410
00411 glEnd();
00412 #endif
00413 return true;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423 void IK_ACA::SetStartConfig( const Configuration& config )
00424 {
00425
00426 if (( startNode != nil ) && ( GetStartConfig() == config ))
00427 {
00428
00429 return;
00430 }
00431
00432
00433 ClearGraph();
00434 searchPath.clear();
00435
00436
00437
00438 PL_GraphBase::SetStartConfig( config );
00439
00440
00441 assert( startNode != nil );
00442
00443
00444 CreateEmbryos( startNode );
00445
00446
00447 this->InitNewSearch();
00448
00449
00450 }
00451
00452
00453
00454
00455
00456
00457
00458 void IK_ACA::SetGoalConfig( const Configuration& config )
00459 {
00460
00461 if ( config != GetGoalConfig() )
00462 {
00463
00464 IK_InvKinBase::SetGoalConfig( config );
00465 }
00466
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476 void IK_ACA::AssignGoalConfig( const Configuration& config )
00477 {
00478
00479 IK_InvKinBase::AssignGoalConfig( config );
00480
00481
00482 PL_GraphBase::SetGoalConfig( config );
00483
00484
00485 for ( int i = 0; i < embryosPerLandmark; i++ )
00486 {
00487 embryo[i][goalNode] = config;
00488 }
00489
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514 void IK_ACA::CopySettings( PlannerBase* original )
00515 {
00516
00517 IK_InvKinBase::CopySettings( original );
00518 PL_GraphBase::CopySettings( original );
00519
00520 IK_ACA* originalACA = dynamic_cast< IK_ACA* >( original );
00521 if( originalACA == NULL )
00522 {
00523 return;
00524 }
00525
00526
00527 SetEmbryosPerLandmark( originalACA->embryosPerLandmark );
00528
00529
00530 InitNewSearch();
00531
00532
00533 }
00534
00535
00536
00537
00538
00539
00540 void IK_ACA::CreateEmbryos (const node& landmark )
00541 {
00542 for (int i = 0; i < embryosPerLandmark; i++ )
00543 {
00544 CreateEmbryo( landmark, i );
00545 }
00546
00547 }
00548
00549
00550
00551
00552
00553
00554
00555 void IK_ACA::CreateEmbryo(const node& landmark, const int& embryoID)
00556 {
00557
00558
00559 Configuration landmarkConfig = G.inf( landmark );
00560 Configuration newconfig = GenerateRandomConfig( landmarkConfig );
00561 Configuration start = GetStartConfig();
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 if ( IsInterfering( landmarkConfig, newconfig ) )
00572 {
00573
00574
00575 newconfig = PL_GraphBase::collisionDetector->GetLastIntersection();
00576 newconfig = GetMidPoint( landmarkConfig, newconfig );
00577
00578
00579 }
00580
00581
00582 embryo[embryoID][landmark] = newconfig;
00583
00584
00585 }
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 node IK_ACA::Explore()
00599 {
00600 double landmark_dist = 0;
00601
00602 node n1, n2, parentNode;
00603 double distance, min_dist;
00604 int embryoID;
00605
00606
00607 forall_nodes(n1, G)
00608 {
00609 for( int i = 0; i < embryosPerLandmark; i++)
00610 {
00611 min_dist = INFINITY;
00612 forall_nodes(n2, G)
00613 {
00614 distance = Distance( embryo[i][n1] , G.inf(n2) );
00615 if ( distance < min_dist )
00616 {
00617 min_dist = distance;
00618 }
00619 }
00620
00621 if ( min_dist > landmark_dist )
00622 {
00623
00624 parentNode = n1;
00625 embryoID = i;
00626 landmark_dist = min_dist;
00627 }
00628 }
00629 }
00630
00631
00632 n1 = G.new_node( G.last_node(), embryo[embryoID][parentNode], LEDA::after);
00633
00634
00635 distance = sqrt( Distance( n1, parentNode ) );
00636 G.new_edge( n1, parentNode, distance );
00637
00638
00639
00640 CreateEmbryo( parentNode, embryoID );
00641 CreateEmbryos( n1 );
00642
00643
00644 return n1;
00645
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659 SuccessResultType IK_ACA::Search( const node& landmark )
00660 {
00661
00662 Semaphore semaphore( guid );
00663 if( this->m_UseSemaphores == true )
00664 {
00665 semaphore.Lock();
00666 }
00667
00668
00669 searchPath.clear();
00670 searchPath.append( G.inf(landmark) );
00671
00672 while ( !HasTimeLimitExpired() )
00673 {
00674 list<Configuration> minPath;
00675 Configuration q0 = searchPath.back();
00676 Configuration q1 = MinimizeDistance( q0 , minPath );
00677
00678
00679 Matrix4x4 toolFrame = GetToolFrame( q1 );
00680
00681
00682 if ( q1.Compare( q0 , DEFAULT_TOL1 ) )
00683 {
00684
00685
00686
00687 double dist_sq = FrameDistance( goalFrame, toolFrame );
00688 if ( dist_sq < bestDistance_sq )
00689 {
00690
00691 bestDistance_sq = dist_sq;
00692 bestLandmark = landmark;
00693 bestPath = searchPath;
00694 }
00695
00696
00697 semaphore.Unlock();
00698 return FAIL;
00699 }
00700
00701
00702 if ( !IsInterfering( q0, q1 ) )
00703 {
00704
00705 searchPath.append( q1 );
00706 }
00707 else
00708 {
00709
00710 searchPath.conc( minPath , LEDA::after );
00711 }
00712
00713
00714
00715 double distToGoal = FrameDistance(goalFrame, toolFrame);
00716 if ( distToGoal < DEFAULT_TOL )
00717
00718
00719
00720 {
00721
00722 semaphore.Unlock();
00723 return PASS;
00724 }
00725
00726 semaphore.Unlock();
00727 semaphore.Lock();
00728
00729 }
00730
00731
00732
00733 semaphore.Unlock();
00734 return TIMER_EXPIRED;
00735
00736 }
00737
00738 SuccessResultType IK_ACA::Search1( const node& landmark )
00739 {
00740
00741 Semaphore semaphore( guid );
00742 if( this->m_UseSemaphores == true )
00743 {
00744 semaphore.Lock();
00745 }
00746
00747
00748 searchPath.clear();
00749
00750 searchPath.append( G.inf(landmark) );
00751
00752
00753 Configuration gh=searchPath.back();
00754
00755 Matrix4x4 toolFrame = GetToolFrame( gh );
00756
00757 double distToGoal = FrameDistance(goalFrame, toolFrame);
00758 if ( distToGoal < DEFAULT_TOL )
00759
00760 {
00761
00762 semaphore.Unlock();
00763 return PASS;
00764 }
00765
00766 while ( !HasTimeLimitExpired() )
00767 {
00768 Configuration q0 = searchPath.back();
00769 Configuration q1 = GetNextConfig( q0 );
00770
00771 for (int i = 0; i<q0.DOF(); i++)
00772 {
00773 if ( q1[i] < collisionDetector->JointMin(i) )
00774 q1[i] = collisionDetector->JointMin(i);
00775 else if ( q1[i] > collisionDetector->JointMax(i) )
00776 q1[i] = collisionDetector->JointMax(i);
00777 }
00778
00779
00780 if ( q1.Compare( q0 , DEFAULT_TOL1*DEFAULT_TOL1 ) )
00781 {
00782
00783 double dist_sq = FrameDistance( goalFrame, toolFrame );
00784 if ( dist_sq < bestDistance_sq )
00785 {
00786
00787 bestDistance_sq = dist_sq;
00788 bestLandmark = landmark;
00789 bestPath = searchPath;
00790 }
00791
00792
00793 semaphore.Unlock();
00794 return FAIL;
00795 }
00796
00797
00798 toolFrame = GetToolFrame( q1 );
00799
00800 distToGoal = FrameDistance(goalFrame, toolFrame);
00801 if ( distToGoal < DEFAULT_TOL )
00802
00803 {
00804
00805 searchPath.append( q1 );
00806 semaphore.Unlock();
00807 return PASS;
00808 }
00809
00810 if (IsInterfering(q1))
00811 {
00812 semaphore.Unlock();
00813 return FAIL;
00814 }
00815
00816
00817 searchPath.append( q1 );
00818
00819 semaphore.Unlock();
00820 semaphore.Lock();
00821 }
00822
00823
00824
00825 semaphore.Unlock();
00826 return TIMER_EXPIRED;
00827 }
00828
00829 VectorN IK_ACA::ComputeEndEffDiff(Matrix4x4 &frStart, Matrix4x4 &frEnd)
00830 {
00831 VectorN returnMe;
00832 returnMe.SetLength(6);
00833
00834 int index = 0;
00835 returnMe[index++] = frEnd(0, 3) - frStart(0, 3);
00836 returnMe[index++] = frEnd(1, 3) - frStart(1, 3);
00837 returnMe[index++] = frEnd(2, 3) - frStart(2, 3);
00838
00839
00840 Matrix4x4 rotated = frEnd * frStart.Inverse();
00841 double temp = rotated.values[0][0] + rotated.values[1][1] + rotated.values[2][2] - 1;
00842 assert(fabs(temp) <= (2+1e-5));
00843 if (temp>2.)
00844 temp = 2.0;
00845 else if (temp<-2.)
00846 temp = -2.0;
00847 double angle = acos(temp/2);
00848 Vector4 axis;
00849 axis[0] = rotated.values[2][1] - rotated.values[1][2];
00850 axis[1] = rotated.values[0][2] - rotated.values[2][0];
00851 axis[2] = rotated.values[1][0] - rotated.values[0][1];
00852
00853 if (sin(angle) != 0)
00854 axis /= (2*sin(angle));
00855
00856 axis *= angle;
00857
00858 returnMe[index++] = axis[0];
00859 returnMe[index++] = axis[1];
00860 returnMe[index++] = axis[2];
00861
00862 return returnMe;
00863 }
00864
00865 Configuration IK_ACA::GetNextConfig( Configuration& q0 )
00866 {
00867 Matrix4x4 current_tool_frame=GetToolFrame(q0);
00868 VectorN Start_Goal_Diff=ComputeEndEffDiff(current_tool_frame, goalFrame);
00869 if (Start_Goal_Diff.Magnitude() > SAMPLING_TIME)
00870 {
00871 Start_Goal_Diff.Normalize();
00872 Start_Goal_Diff*=SAMPLING_TIME;
00873 }
00874 Frame identity;
00875 jacobian->SetConfiguration(q0);
00876 jacobian->SetInterestPoint(q0.DOF()-1, identity, true, true);
00877 VectorN jointDiff;
00878 jacobian->GetJointVelocity(jointDiff, Start_Goal_Diff);
00879
00880 Configuration q1=q0+jointDiff*Rad2Deg(1);
00881
00882 return q1;
00883 }
00884
00885
00886
00887
00888
00889
00890
00891 void IK_ACA::SetCollisionDetector (CollisionDetectorBase* collisionDetector)
00892 {
00893
00894 CD_BasicStyle* basicStyle = dynamic_cast< CD_BasicStyle* >( collisionDetector );
00895 assert( basicStyle != NULL );
00896 if( basicStyle != NULL )
00897 {
00898 R_OpenChain * robot;
00899 robot = dynamic_cast<R_OpenChain*>(basicStyle->GetRobot(0));
00900 jacobian = new CJacobian(*robot);
00901
00902
00903 PL_GraphBase::SetCollisionDetector( basicStyle );
00904 }
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917 double IK_ACA::FindJointAdjust( const unsigned int& jointNum, const Matrix4x4& toolFrame ) const
00918 {
00919
00920
00921 FrameManager* frameManager = collisionDetector->GetFrameManager();
00922
00923
00924 Matrix4x4 linkFrame = frameManager->GetWorldFrame( collisionDetector->JointFrameNum( jointNum ) );
00925
00926
00927 Matrix4x4 goalWRTlinkFrame = FrameManager::GetTransformRelative( goalFrame, linkFrame );
00928 #ifdef _USE_ORIENTATION_
00929 Vector4 Pgx = goalWRTlinkFrame * PX;
00930 Vector4 Pgy = goalWRTlinkFrame * PY;
00931 Vector4 Pgz = goalWRTlinkFrame * PZ;
00932 #else
00933 Vector4 goalVec;
00934 goalVec[0] = goalWRTlinkFrame(0, 3);
00935 goalVec[1] = goalWRTlinkFrame(1, 3);
00936 goalVec[2] = goalWRTlinkFrame(2, 3);
00937 #endif
00938
00939
00940 Matrix4x4 toolWRTlinkFrame = FrameManager::GetTransformRelative( toolFrame, linkFrame );
00941 #ifdef _USE_ORIENTATION_
00942 Vector4 Ptx = toolWRTlinkFrame * PX;
00943 Vector4 Pty = toolWRTlinkFrame * PY;
00944 Vector4 Ptz = toolWRTlinkFrame * PZ;
00945 #else
00946 Vector4 toolVec;
00947 toolVec[0] = toolWRTlinkFrame(0, 3);
00948 toolVec[1] = toolWRTlinkFrame(1, 3);
00949 toolVec[2] = toolWRTlinkFrame(2, 3);
00950 #endif
00951
00952
00953 double adjustment;
00954
00955
00956 DH_Parameter jointType = collisionDetector->JointType( jointNum );
00957 switch ( jointType )
00958 {
00959 case DH_THETA :
00960 {
00961
00962
00963
00964
00965 #ifdef _USE_ORIENTATION_
00966 double a = Pgz[1]*Ptz[1] + Pgz[0]*Ptz[0] + Pgy[0]*Pty[0] + Pgy[1]*Pty[1] + Pgx[0]*Ptx[0] + Pgx[1]*Ptx[1];
00967 double b = Pgz[1]*Ptz[0] - Pgz[0]*Ptz[1] - Pgy[0]*Pty[1] + Pgy[1]*Pty[0] + Ptx[0]*Pgx[1] - Ptx[1]*Pgx[0];
00968 #else
00969 double a = goalVec[0]*toolVec[0] + goalVec[1]*toolVec[1];
00970 double b = -goalVec[0]*toolVec[1] + toolVec[0]*goalVec[1];
00971 #endif
00972 double theta1 = atan2( b , a );
00973 double theta2;
00974 if ( theta1 > 0 )
00975 {
00976 theta2 = theta1 - M_PI;
00977 }
00978 else
00979 {
00980 theta2 = theta1 + M_PI;
00981 }
00982
00983
00984 double val1 = -a*cos(theta1) - b*sin(theta1);
00985 double val2 = -a*cos(theta2) - b*sin(theta2);
00986 if ( val1 < val2 )
00987 {
00988 adjustment = Rad2Deg( theta1 );
00989 }
00990 else
00991 {
00992 adjustment = Rad2Deg( theta2 );
00993 }
00994 }
00995 break;
00996 case DH_ALPHA :
00997 {
00998
00999
01000
01001
01002 #ifdef _USE_ORIENTATION_
01003 double b = Pgy[2]*Pty[1] - Pgy[1]*Pty[2] - Ptx[2]*Pgx[1] + Ptx[1]*Pgx[2] - Pgz[1]*Ptz[2] + Pgz[2]*Ptz[1];
01004 double a = Pgz[1]*Ptz[1] + Pgz[2]*Ptz[2] + Pgy[1]*Pty[1] + Pgy[2]*Pty[2] + Pgx[1]*Ptx[1] + Pgx[2]*Ptx[2];
01005 #else
01006 assert(false);
01007 double b = 1;
01008 double a = 1;
01009 #endif
01010
01011 double alpha1 = atan2( b , a );
01012 double alpha2;
01013 if ( alpha1 > 0 )
01014 {
01015 alpha2 = alpha1 - M_PI;
01016 }
01017 else
01018 {
01019 alpha2 = alpha1 + M_PI;
01020 }
01021
01022
01023 double val1 = -a*cos(alpha1) - b*sin(alpha1);
01024 double val2 = -a*cos(alpha2) - b*sin(alpha2);
01025 if ( val1 < val2 )
01026 {
01027 adjustment = Rad2Deg( alpha1 );
01028 }
01029 else
01030 {
01031 adjustment = Rad2Deg( alpha2 );
01032 }
01033 }
01034 break;
01035 case DH_D :
01036 {
01037
01038
01039
01040 #ifdef _USE_ORIENTATION_
01041 adjustment = ( Pgz[2] + Pgy[2] - Ptx[2] + Pgx[2] - Pty[2] - Ptz[2] ) / 3;
01042 #else
01043 adjustment = 0;
01044 #endif
01045 }
01046 break;
01047 case DH_A :
01048 {
01049
01050
01051
01052 #ifdef _USE_ORIENTATION_
01053 adjustment = ( Pgz[0] + Pgy[0] - Ptx[0] + Pgx[0] - Pty[0] - Ptz[0] ) / 3;
01054 #else
01055 adjustment = 0;
01056 #endif
01057 }
01058 break;
01059 default :
01060 adjustment = 0;
01061 }
01062
01063
01064 return adjustment;
01065
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075 Configuration IK_ACA::MinimizeDistance( const Configuration& config , list<Configuration>& minPath )
01076 {
01077
01078 Configuration minConfig = config;
01079 minPath.clear();
01080
01081
01082 int dof = collisionDetector->DOF();
01083 for ( int i = 0; i < dof; i++ )
01084 {
01085
01086 Matrix4x4 toolFrame = GetToolFrame( minConfig );
01087
01088
01089 double jointAdjust = minConfig[i] + FindJointAdjust( i, toolFrame );
01090
01091
01092 double jmax = collisionDetector->JointMax( i );
01093 double jmin = collisionDetector->JointMin( i );
01094 if ( collisionDetector->JointWraps( i ) )
01095 {
01096 if ( jointAdjust > jmax )
01097 {
01098 jointAdjust -= ( jmax - jmin );
01099 }
01100 else if ( jointAdjust < jmin )
01101 {
01102 jointAdjust += ( jmax - jmin );
01103 }
01104 }
01105 else
01106 {
01107 if ( jointAdjust > jmax )
01108 {
01109 jointAdjust = jmax;
01110 }
01111 if ( jointAdjust < jmin )
01112 {
01113 jointAdjust = jmin;
01114 }
01115 }
01116
01117
01118 Configuration newConfig = minConfig;
01119 newConfig[ i ] = jointAdjust;
01120
01121
01122 if ( IsInterfering( minConfig, newConfig ) )
01123 {
01124
01125 minConfig = collisionDetector->GetLastValid();
01126 }
01127 else
01128 {
01129
01130 minConfig[ i ] = jointAdjust;
01131 }
01132
01133 minPath.append( minConfig );
01134
01135 }
01136
01137 return minConfig;
01138
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 double IK_ACA::FrameDistance ( const Matrix4x4& frameA, const Matrix4x4& frameB ) const
01152 {
01153 #ifdef _USE_ORIENTATION_
01154
01155 Vector4 Pax = frameA * PX;
01156 Vector4 Pay = frameA * PY;
01157 Vector4 Paz = frameA * PZ;
01158
01159 Vector4 Pbx = frameB * PX;
01160 Vector4 Pby = frameB * PY;
01161 Vector4 Pbz = frameB * PZ;
01162
01163
01164 Vector4 dx = Pax - Pbx;
01165 Vector4 dy = Pay - Pby;
01166 Vector4 dz = Paz - Pbz;
01167
01168
01169 double distance_sq = dx.MagSquared() + dy.MagSquared() + dz.MagSquared();
01170 #else
01171 Vector4 offset1, offset2;
01172 offset1[0] = frameA(0, 3);
01173 offset1[1] = frameA(1, 3);
01174 offset1[2] = frameA(2, 3);
01175
01176 offset2[0] = frameB(0, 3);
01177 offset2[1] = frameB(1, 3);
01178 offset2[2] = frameB(2, 3);
01179
01180 offset1 -= offset2;
01181
01182 double distance_sq = offset1.MagSquared();
01183 #endif
01184
01185
01186 return distance_sq;
01187
01188 }
01189
01190
01191
01192
01193
01194
01195 int IK_ACA::GetEmbryosPerLandmark() const
01196 {
01197 return embryosPerLandmark;
01198 }
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 void IK_ACA::SetEmbryosPerLandmark( const int& num_of_embryos )
01212 {
01213 if ( num_of_embryos == embryosPerLandmark )
01214 {
01215
01216 return;
01217 }
01218
01219
01220 node_map<Configuration>* old_embryo = embryo;
01221 assert( old_embryo != NULL );
01222
01223
01224 int old_embryosPerLandmark = embryosPerLandmark;
01225 if ( num_of_embryos < 1 )
01226 {
01227 embryosPerLandmark = 1;
01228 }
01229 else
01230 {
01231 embryosPerLandmark = num_of_embryos;
01232 }
01233
01234
01235
01236 embryo = new node_map<Configuration>[embryosPerLandmark];
01237 assert( embryo != NULL );
01238 for ( int i = 0; i < embryosPerLandmark; i++ )
01239 {
01240 embryo[i].init(G);
01241 }
01242
01243
01244 node n1;
01245 forall_nodes( n1, G )
01246 {
01247 for( int i = 0; i < embryosPerLandmark; i++ )
01248 {
01249 if ( i < old_embryosPerLandmark )
01250 {
01251
01252 embryo[i][n1] = old_embryo[i][n1];
01253 }
01254 else
01255 {
01256
01257 CreateEmbryo( n1, i );
01258 }
01259 }
01260 }
01261
01262
01263 delete [] old_embryo;
01264
01265 }
01266
01267
01268
01269
01270
01271
01272 void IK_ACA::InitNewSearch()
01273 {
01274
01275 searchLandmark = startNode;
01276
01277
01278
01279 SetGoalConfig( GetStartConfig() );
01280
01281
01282 InitBestParams();
01283
01284 }
01285
01286
01287
01288
01289
01290
01291 void IK_ACA::InitBestParams()
01292 {
01293 bestLandmark = startNode;
01294 bestPath.clear();
01295
01296 if ( collisionDetector != NULL )
01297 {
01298 bestDistance_sq = FrameDistance( goalFrame, GetToolFrame( GetGoalConfig() ) );
01299 }
01300 else
01301 {
01302 bestDistance_sq = INFINITY;
01303 }
01304 }
01305
01306
01307
01308
01309
01310
01311
01312 SuccessResultType IK_ACA::ComputePath ( const node& landmark, const list<Configuration>& myPath )
01313 {
01314
01315
01316 ClearGraphPath();
01317 node n0 = landmark;
01318 graphPath.push( n0 );
01319 while ( n0 != startNode )
01320 {
01321 n0 = G.target( G.first_adj_edge( n0 ) );
01322 graphPath.push( n0 );
01323 }
01324
01325
01326 SuccessResultType success = TranslatePath();
01327
01328
01329 list_item last = myPath.last();
01330 list_item index = myPath.first();
01331 while ( index != last )
01332 {
01333 index = myPath.succ( index );
01334 path.AppendPoint( myPath.inf(index) );
01335 }
01336
01337
01338 AssignGoalConfig( myPath.inf( index ) );
01339
01340 return success;
01341
01342 }