Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

robot/control/oldikor/IKOR/IKOR_driver.c

Go to the documentation of this file.
00001 /* ________________________________________________________
00002   |                                                        |
00003   | Program Name:   IKOR_driver.c                          |
00004   |________________________________________________________|
00005   |                                                        |
00006   | description:  Driver for FSP, Psuedo Inverse, Manipul- |
00007   |     ator porting, obstacle detection, and utilities.   |
00008   |     IKOR_driver does not contain a main, instead it can|
00009   |     be called by the main in short.c or CheezyIGRIP.c  |
00010   |     or any other.                                      |
00011   |                                                        |
00012   | Procedures:                                            |
00013   |     IKOR_driver    :                                   |
00014   |     CALC_PSEUDO    :                                   |
00015   |     FSP            :                                   |
00016   |     Euler_to_Velocities :                              |
00017   |     correct_euler  :                                   |
00018   |     OPEN_FILES     :                                   |
00019   |     Update_History :                                   |
00020   |     Init_Globals   :                                   |
00021   |________________________________________________________| */
00022 
00023 
00024 #include <IKOR/general.h>       /* Generic Constants               */
00025 #include <IKOR/Globals.h>       /* Global Variables used by system */
00026 
00027 #define DEBUG_OUT 1
00028 
00029 /* ________________________________________________________
00030   | name:    IKOR_driver                                   |
00031   | description:  Drives entire system, although main is   |
00032   |     not here (see short.c or CheezyIGRIP.c for main).  |
00033   |     Initializes global variables, reads in manipulator |
00034   |     trajectory files, calls Jacobian, FSP, and con-    |
00035   |     straint avoidance routines, if wanted. Also allows |
00036   |     for Moore-Penrose Pseudo Inverse solutions, however|
00037   |     the Pseudo is not equipped for constraint avoidance|
00038   |                                                        |
00039   | inputs:  N, M, method.  Manipulator, trajectory        |
00040   | outputs: Alters two variables within FSP_data.         |
00041   |     the beta vector for the joint is added to betall,  |
00042   |     and cn, the number of beta vectors present, is     |
00043   |     incremented.                                       |
00044   |________________________________________________________|
00045   | Authors:     Date:     Modifications:                  |
00046   |  F Tulloch     4/94    Algorithm Creation for 2 g's    |
00047   |  c hacker     10/94    Ported from 2 g's to FSP        |
00048   |                2/95    Ported to Solutions struct      |
00049   |                3/95    Altered FSP, Pseudo calls       |
00050   |________________________________________________________| */
00051 
00052 int IKOR_driver(IKCriterion, IKMethod, Optimization, N_use, M_use)
00053 int *IKCriterion,    /* Psuedo-Inverse, FSPleastnorm or leastflow  */
00054     *IKMethod,       /* Constraints : jointlimits, obstacles...    */
00055      Optimization,   /* Lagrangian, BANGBANG, SIMPLEX              */
00056      M_use,          /* Size of Joint Space (!> num angles)        */
00057      N_use;          /* Size of Task Space (x,y,z,yw,ptch,rll)     */
00058 {
00059   int    i, j, k,                       /* Generic counters               */
00060          ns,                            /* Number of Spheres              */
00061          STEP,                          /* Current Step Along Trajectory  */
00062          Num_Of_Pts,                    /* Number of points in Trajectory */
00063          quit = 0;                      /* Exit_Status:  -2 File Trouble  */
00064                                         /*               -1 Partial Traj  */
00065   float  distance;                      /* Determines distance traveled   */
00066   double XTraj[MAX_PTS][6],             /* End Effector (EE) Coordinates  */
00067          spheredata[4][4];              /* Holds sphere info              */
00068   MATRIX *Jacob,                        /* Holds Forward Kinematic Deriv. */
00069          *dx,                           /* Holds change in "EE"           */
00070          *dq,                           /* Holds change in ANGLES         */
00071          *x_of_link,                    /* Holds end points of each link  */
00072          *Pos_error;                    /* Holds the error in position    */
00073   Solutions *FSP_data;                  /* see structure.h for explanation*/
00074   History   Old_DQs;                    /* Contains Array of History      */
00075 
00076  /*--------------------------------------------------------------*
00077    * GLOBAL and LOCAL INITIALIZATIONS  (Order of decls important) *
00078    *--------------------------------------------------------------*/
00079   N=N_use;
00080   M=M_use;
00081   Old_DQs.whereami = -1;
00082   for (i=0; i<HIST_SIZE; i++)
00083      Old_DQs.dq[i].DQ = mat_malloc( M , 1 );
00084   Pos_error = mat_malloc(N, 1); /* memory for error  in position  */
00085   dx        = mat_malloc(N, 1); /* memory for change in position  */
00086   Jacob     = mat_malloc(N, M); /* memory for Forw.Kin. derivatve */
00087                                 /* memory for x,y,z of each link  */
00088   x_of_link=mat_malloc(Robot->NL+1,N);
00089   FSP_data =Solutions_init(M,N);/* memory for solutions,betas, etc*/
00090                                 /* initailize trajectory, data... */
00091   if (!(Num_Of_Pts=OPEN_FILES(XTraj, PoorMansFile, FSP_data->Qarray)))
00092          return (-2);
00093   ns=spheres(spheredata,datafp);/* initialize obstacles in system */ 
00094   dq = mat_malloc(M,1);
00095   Update_History(&Old_DQs, dq);
00096   mat_free(dq);
00097   /* correct size of the Weight MATRIX, see structures.h,        */
00098   Robot->Weights->rows = Robot->Weights->cols = M;
00099 
00100  
00101   /*--------------------------------------------------------------*
00102    * Uncomment, to trace bus errors or segmentation faults        *
00103    *--------------------------------------------------------------*/
00104   /*datafp = stderr;            /* When in trouble, uncomment     */
00105 
00106 
00107   /*-------------------------------------------------------------*
00108    *       HEADER INFORMATION for Standard Output                *
00109    *-------------------------------------------------------------*/
00110 
00111   #ifdef DEBUG_OUT
00112     fprintf (stderr, "\n\n\n"
00113                    " *********************************************\n"
00114                    "   INVERSE KINEMATIC AND REDUNDANCY RESOLVER  \n"
00115                    "   For HERMIES CESARm, %d D.O.F, %d D.O.R.    \n"
00116                    " *********************************************", M,M-N);
00117     fprintf (stderr, "\n\n\n"
00118                    "     < NUMBER OF POINTS IN TRAJECTORY >  %d  \n"
00119                    "         << Time Step >>                     \n"
00120                    "          ---------------------              \n"
00121                    "\n<< -1>>", Num_Of_Pts);
00122   #endif
00123   
00124   /*----------------------------------------------------------------*
00125    *                          MAIN-LOOP                             *  
00126    *                                                                *
00127    *    Cycles through all points on trajectory until done doing    *
00128    *    Least Norm  and possibly Joint and Obstacle Avoidance until *
00129    *    an unavoidable problem occurs.                              *
00130    *----------------------------------------------------------------*/
00131 
00132   for (STEP = 0; STEP < Num_Of_Pts ; STEP++)
00133   { /*main_loop*/
00134 
00135     /*-------------------------------------------------------*
00136      * Print Angles for simulation programs (IGRIP, Cheeze)  *
00137      *    and print step number to the data and stderr files *
00138      *-------------------------------------------------------*/
00139 
00140     for (i=0;i< Robot->NA;i++)
00141       if (i<M) fprintf (CheezyFile, "%f  ", FSP_data->Qarray->p[i][0]);
00142     fprintf (CheezyFile, "  \n");
00143     fflush  (CheezyFile);
00144 
00145     if (DEBUG) 
00146       fprintf (datafp, "\n*************STEP <%d> ****************\n", STEP+1);
00147     #ifdef DEBUG_OUT
00148       fprintf (stderr, "\r<<%3d>>", STEP+1);
00149     #endif
00150 
00151     /*-------------------------------------------------------*
00152      * Based on Angles, Calculates Position of End Effector  *
00153      *-------------------------------------------------------*/
00154     #ifndef FSP_DEBUG
00155       GET_JACOBIAN(Jacob, FSP_data->Qarray);
00156       GET_ACTUAL_X(FSP_data->Qarray, x_of_link);
00157 
00158       if (DEBUG) {
00159         fmat_pr (datafp, "Jacobian for Current Configuration", Jacob);
00160         fprintf (datafp, "\nCurrent Position\n"    );
00161         for (i = 0; i <  N; i++)
00162           fprintf(datafp,"%s : %9f\n", dxLabel[i], x_of_link->p[Robot->NL][i]);
00163         fprintf (datafp, "Next Point in Trajectory\n");
00164       }
00165 
00166       /*----------------------GET DX'S-------------------------*
00167        *  Based on actual position, Calculates Change in X nec *
00168        *  This feedback loop is necessary because this system  *
00169        *  is highly nonlinear.                                 *
00170        *-------------------------------------------------------*/
00171       for (i = 0; i <  N; i++)
00172       {
00173         if (DEBUG) fprintf(datafp,"%s : %9f\n", dxLabel[i], XTraj[STEP][i]);    
00174         dx -> p[i][0] = XTraj[STEP][i] - x_of_link->p[Robot->NL][i];
00175         Pos_error->p[i][0]=XTraj[STEP?STEP-1:0][i] - x_of_link->p[Robot->NL][i];
00176         if ( fabs( dx->p[i][0] ) < SMALL ) dx->p[i][0]=ZERO;
00177         if (( i < 3) && ( fabs(dx->p[i][0]) > BIG) ) IKerror(26,OK,dxLabel[i]);
00178       }                      
00179 
00180       if (DEBUG) fmat_prf(datafp,"Pos Error (Cur Pos - Prev Target)",Pos_error);
00181 
00182       /*--------------------------------------------------------*
00183        * CONVERT INCREMENTAL EULER ANGLES INTO INCREMENTAL      *
00184        * ANGLES ABOUT EACH AXIS OF BASE FRAME                   *
00185        *--------------------------------------------------------*/
00186 
00187       if (Robot->Orient)
00188       {
00189         /* fix the 180 == -180 problem for yaw and roll, see correct_euler() */
00190         dx->p[3][0] =
00191         correct_euler( dx->p[3][0],x_of_link->p[Robot->NL][3],XTraj[STEP+1][3]);
00192         dx->p[5][0] =
00193         correct_euler( dx->p[5][0],x_of_link->p[Robot->NL][5],XTraj[STEP+1][5]);
00194 
00195         Euler_to_Velocities (x_of_link, dx);
00196         if (Robot->Orient == ZEROD_OMEGAS) 
00197           dx->p[3][0]=dx->p[4][0]=dx->p[5][0]=ZERO;
00198       }
00199     #else
00200       GetData(Jacob, dx);
00201       STEP = Num_Of_Pts;
00202     #endif
00203     
00204     /*-------------------------------------------------------*
00205      * CALCULATE dq'S USING ALGORITHM Selected by IKMethod   *
00206      *-------------------------------------------------------*/
00207 
00208     FSP_data->cn = 0;      /* reintialize num of constraints for each STEP */
00209     if (IKCriterion[0] != 1) 
00210       dq = FSP (FSP_data, &Old_DQs, Jacob, dx, IKCriterion, IKMethod, 
00211                         Optimization, ns, spheredata, x_of_link, datafp);
00212     else
00213       dq = CALC_PSEUDO (Jacob, dx);
00214     if (dq== (MATRIX *) -1) break;
00215  
00216     /*-----------------------------------------------------------*
00217      *  Determine Distance Traveled                              *
00218      *-----------------------------------------------------------*/
00219 
00220     /*-----------------------------------------------------------*
00221      *   Now add the necessary changes in angles to the current  *
00222      *   Angles and keep values within 4 PI                      *
00223      *-----------------------------------------------------------*/
00224     for (i = 0; i < M; i++)
00225     {
00226       if ((IKCriterion[0]!=1)&&(fabs(FSP_data->Xelim->p[i][0]) > SMALL))
00227         dq->p[i][0] = FSP_data->Xelim->p[i][0];
00228 
00229       FSP_data->Qarray->p[i][0] += dq-> p[i][0];
00230 
00231       if (!Robot->Angles[i].Prism)
00232       {
00233         if (FSP_data->Qarray->p[i][0] >  2*PI) 
00234             FSP_data->Qarray->p[i][0] -= 2*PI;
00235         if (FSP_data->Qarray->p[i][0] < -2*PI) 
00236             FSP_data->Qarray->p[i][0] += 2*PI;
00237       }         /* end if ! prism */
00238     }   /* end for i=1 to M */
00239 
00240     mat_mul(Jacob,dq,dx);
00241     distance = ZERO;
00242     for (i = 0; i<3; i++) distance += dx->p[i][0] * dx->p[i][0];
00243       distance = sqrt (distance);
00244     for (i = 0; i < M; i++) {
00245       fprintf(dqfile, "%10.7f", dq->p[i][0]);
00246       /* specific calculations for hydrolic action of AIRARM joints */
00247       /*  calc_flow(i, FSP_data->Qarray->p[i][0], dq->p[i][0], 
00248             distance, (MATRIX *) 0); 
00249       */
00250     }
00251     fprintf(dqfile,"\n");
00252 
00253     Update_History(&Old_DQs, dq);
00254 
00255     if (DEBUG) {
00256       fmat_prf(datafp, "dq (radians)", dq);
00257       fmat_prf(datafp, "resulting dx", dx); 
00258       fmat_prf(datafp, "Qarray (radians)", FSP_data->Qarray);
00259     }
00260 
00261     #ifdef DEBUG_OUT
00262     /*  if ((STEP%20)==1) /* uncomment for shorter output */
00263       fprint_norm( NormFile, dq, datafp );
00264     /*  fprint_norm( ErrorFile, Pos_error, datafp ); */
00265     #endif
00266     mat_free(dq);           /* free up dq for next step or end  */
00267 
00268     if (quit < 0) break;    /* If unavoidable trouble quit      */
00269   }  /* END MAIN FOR LOOP*/
00270 
00271 
00272 
00273   /*-------------------------------------------------------------*
00274    *                         FINAL SUMMARY                       *
00275    *-------------------------------------------------------------*/
00276   fprintf (datafp, "\n\n ----FINAL SUMMARY------\n"
00277                        " --- Exit Status: %d ---\n"
00278                        " Errors in final point:  \n", quit);
00279 
00280   fprintf (datafp, "\nStarting Coordinates:\n");
00281   for (i = 0; i < N; i++)
00282     fprintf (datafp, "Element [%d] >%f\n", i, XTraj[0][i]);
00283 
00284   fprintf (datafp, "\nRequested Ending Coordinates\n");
00285   for (i = 0; i < N; i++)
00286     fprintf (datafp, "Element [%d] >%f\n", i, XTraj[Num_Of_Pts-1][i]);
00287 
00288   fmat_pr (datafp, "Actual Ending Coordinates:", x_of_link);
00289 
00290   #ifdef DEBUG_OUT
00291     fprintf (stderr,"\n DATA FILE %s HAS BEEN CREATED AND CONTAINS\n"
00292                       " THE ANGLES FOR THE MANIPULATOR FOR EACH TIME  \n"
00293                       " STEP.  EXAMINE, OR RUN IT THROUGH A SIMULATOR.\n", 
00294                         PoorMansFile);
00295   #endif
00296 
00297   /*------------------------------------------------------------------*
00298    * Clean up Global variables and Close Files                        *
00299    *------------------------------------------------------------------*/
00300   fclose(ErrorFile);
00301   fclose(NormFile);
00302   fclose(CheezyFile);
00303   fclose(datafp);
00304 
00305   Solutions_free(FSP_data);
00306   mat_free(Pos_error);
00307   mat_free(x_of_link);
00308   mat_free(Jacob);
00309   mat_free(dx);
00310   for (i=0; i<HIST_SIZE; i++)
00311     mat_free(Old_DQs.dq[i].DQ);
00312   free (LL);
00313 
00314   return (quit);
00315 }                            /* END IKOR_driver */
00316 
00317 
00318 /* ________________________________________________________
00319   | name:    Euler_to_Velocities                           |
00320   | description:  Converts Euler Angle increments produced |
00321   |       by the forward kinematics into angular velocites |
00322   |       about each of the major axes (X, Y, and Z).  The |
00323   |       conversion matrix can be found in Robotics: Con- |
00324   |       trol, Sensing, Vision, and Intelligence p235.    |
00325   |                                                        |
00326   | inputs:  Euler Angles held in x_of_link, Requested     |
00327   |       change in Euler Angles held in dx.               |
00328   | outputs: Returns requested change in velocites held in |
00329   |       the dx structure.                                |
00330   |________________________________________________________|
00331   | Authors:     Date:     Modifications:                  |
00332   |  c hacker     5/95     implemented                     |
00333   |________________________________________________________| */
00334 
00335 void Euler_to_Velocities (MATRIX *x_of_link, MATRIX *dx)
00336 {
00337   float  dGAMMA, gamma,                 /* Euler Angles with deltas       */
00338          dBETA,  beta,                  /* Euler Angles with deltas       */
00339          dALPHA, alpha;                 /* Euler Angles with deltas       */
00340          
00341 
00342   gamma    = x_of_link->p[Robot->NL][3];      
00343   dGAMMA   = dx->p[3][0];
00344 
00345   beta     = x_of_link->p[Robot->NL][4];
00346   dBETA    = dx->p[4][0];
00347 
00348   alpha    = x_of_link->p[Robot->NL][5];
00349   dALPHA   = dx->p[5][0];
00350 
00351   /* wx */  dx->p[3][0]= dALPHA*cos(gamma)*cos(beta) - dBETA*sin(gamma); 
00352   /* wy */  dx->p[4][0]= dALPHA*sin(gamma)*cos(beta) + dBETA*cos(gamma);
00353   /* wz */  dx->p[5][0]=-dALPHA*sin(beta)            + dGAMMA;
00354 
00355   if (DEBUG) {
00356     fprintf(datafp,"\nEuler Velocity Transforms and Corrections\n");
00357     fprintf(datafp,"\n%s%12.8f%s%12.8f\n%s%12.8f%s%12.8f\n%s%12.8f%s%12.8f\n",
00358                    "YAW  :  gamma    : ", gamma  , "   dGAMMA   : ", dGAMMA,
00359                    "PITCH:  beta     : ", beta   , "   dBETA    : ", dBETA,
00360                    "ROLL :  alpha    : ", alpha  , "   dALPHA   : ", dALPHA );
00361     fprintf(datafp,"dx(wx) : %12.8f\ndx(wy) : %12.8f\ndx(wz) : %12.8f\n",
00362                    (dx->p[3][0]), (dx->p[4][0]), (dx->p[5][0]) );
00363   }
00364 }
00365 
00366 /* ________________________________________________________
00367   | name:    correct_euler                                 |
00368   | description:  Because yaw and pitch are equivalent     |
00369   |       when the angle = 180 and -180 degrees, a dx      |
00370   |       that is calculated at this edge can be erroneous.|
00371   |       That is, -180 - 180 = -360 when the only requir- |
00372   |       required change is really 0.  This code corrects |
00373   |       for this orientation situation.                  |
00374   |                                                        |
00375   | inputs:  yaw or roll, current position, and destina-   |
00376   |       tion position.                                   |
00377   | outputs: Returns corrected change in velocites.        |
00378   |________________________________________________________|
00379   | Authors:     Date:     Modifications:                  |
00380   |  c hacker     5/95     implemented                     |
00381   |________________________________________________________| */
00382 
00383 float correct_euler ( float angle, float curr, float dest )
00384 {
00385 
00386   /* check if faulty condition exists */
00387   if ( fabs( angle ) > PI )
00388   {
00389     if (DEBUG) fprintf(datafp,"\nFaulty orientation velocity, old: %f", angle); 
00390 
00391     angle = PI - fabs(dest) + PI - fabs(curr); 
00392     /* correct for sign */
00393     if (( curr < 0 ) && ( dest > 0 ))
00394        angle = -angle;
00395 
00396     if (DEBUG) fprintf(datafp, "... new: %f\n", angle);
00397   }
00398   /* return corrected or non-corrected angle */
00399   return (angle);
00400 }
00401 
00402 
00403 /* ________________________________________________________
00404   | name:    CALC_PSEUDO                                   |
00405   | description:  Calculate Change in Angles using Pseudo  |
00406   |     Inverse. The procedure prepares the Jacobian and   |
00407   |     calls the routine mat_pseudoinv() found in the     |
00408   |     file matrix.c                                      |
00409   |                                                        |
00410   | inputs:  Jacobian and change in x                      |
00411   | outputs: Returns dq necessary to complete motion.      |
00412   |________________________________________________________|
00413   | Authors:     Date:     Modifications:                  |
00414   |  F Tulloch    4/94     Algorithm Creation for 2 g's    |
00415   |  c hacker     3/95     rearranged calling structure    |
00416   |               3/95     took struct from "struct MATRIX"|
00417   |________________________________________________________| */
00418 
00419 MATRIX *CALC_PSEUDO (MATRIX *Jacob, MATRIX *dx)
00420 {
00421   int    i, j;           /* counter variables                */
00422   MATRIX *Jacobinv,      /* Holds Jacobian Psuedo-inverse    */
00423          *dq;            /* Holds delta angle changes needed */
00424 
00425   Jacobinv = mat_malloc(M,M);
00426 
00427   mat_cp(Jacob, Jacobinv);
00428 
00429   for (i=0;i<M;i++)      /* Must be padded with zeros        */
00430     for (j=N; j< M; j++)
00431       Jacobinv->p[j][i] = 0.0;
00432 
00433   mat_pseudoinv(Jacobinv); /* JacobTemp holds jacob's inverse */
00434 
00435   Jacobinv->cols = N;
00436   dq = mat_mul2(Jacobinv, dx);
00437   Jacobinv->cols = M;
00438 
00439   if (DEBUG) {
00440      fmat_pr(datafp,"*** Jacobian ***",  Jacob);
00441      fmat_prf(datafp,"requested dx",     dx);
00442   }
00443 
00444   mat_free(Jacobinv);
00445   return (dq);  
00446 }
00447 
00448 
00449 /* ________________________________________________________
00450   | name:    FSP                                           |
00451   | description:  This procedure calculates the changes in |
00452   |     angles via the new algorithm (FSP). It also calls  |
00453   |     routines to check for obstacles, limits, ect...    |
00454   |     Finally, a procedure to find a particular para-    |
00455   |     metric solution based on constraints, criteria.    |
00456   |     The reason for several find_t functions is due to  |
00457   |     speed considerations, so that, the find_t that gets|
00458   |     called should be the fastest.                      |
00459   |                                                        |
00460   | inputs:  Jacobian, change in x, IKmethod, sphere data, |
00461   |     and position.                                      |
00462   | outputs: Returns dq necessary to complete motion.      |
00463   |________________________________________________________|
00464   | Authors:     Date:     Modifications:                  |
00465   |  F Tulloch    4/94     Algorithm Creation for 2 g's    |
00466   |  c hacker     3/95     rearranged calling structure    |
00467   |               3/95     took struct from "struct MATRIX"|
00468   |               3/95     converted to ONE STEP Method    |
00469   |________________________________________________________| */
00470 
00471 MATRIX *FSP(FSP_data, Old_DQs, Jacob, dx, IKCriterion, IKMethod, Optimization,
00472                 ns, spheredata, x_of_link, datafp)
00473 FILE   *datafp;            /* data file declaration          */
00474 int     *IKCriterion,      /* Criterion                      */
00475         *IKMethod,         /* 0-JL,2-OBS ... contraints      */
00476          Optimization,     /* LAGRANGE,BANGBANG,SIMPLEX      */
00477          ns;               /* sphere_data (# of spheres)     */
00478 double  spheredata[4][4];  /* sphere_data (rad,x,y,z)        */
00479 MATRIX *dx,                /* change in EE position          */
00480        *Jacob,             /* derivative of Forward Kinematic*/
00481        *x_of_link;         /* position of all links          */
00482 Solutions *FSP_data;       /* see structures.h               */
00483 History *Old_DQs;
00484 {
00485   int     i, j, k,     /* counter variables                   */
00486           got_gs=TRUE, /* For TWOSTEP, flag if 2nd g's made   */
00487           Terminate;   /* Termination Status of FSP           */
00488   MATRIX *dq,          /* final solution for joint space move */
00489          *B,
00490          *H;
00491 
00492   Terminate = Solution_generator(FSP_data, Jacob, dx, datafp); 
00493   if (Terminate == NOT_COMPLETE) IKerror(10, FATAL, "");
00494   B = mat_malloc (  M,    M );
00495   H = mat_malloc (  SPAN, 1 );
00496 
00497   switch (IKCriterion[0]) {
00498      case 0: Least_Norm (B, H, datafp); break;
00499      case 1:  /* This is Least Norm and Should Not Be Called Here */
00500      case 2:  /* MinDx   ();  (implemented in IKORv2.6, not here) */
00501      case 3:  /* MinDist ();  (implemented in IKORv2.6, not here) */
00502      case 4: Least_Flow (B, H, FSP_data->Qarray, datafp);  break;
00503      default: fprintf(stderr, "Requested criterion does not exist! \n");
00504               break;
00505   }
00506 
00507   if (Optimization == BANGBANG)
00508   {
00509     if (IKCriterion[0] == 4)
00510     {
00511       dq = findt_without_Betas_BANGBANG(FSP_data, B, H,
00512                  Old_DQs->dq[Old_DQs->whereami].DQ, datafp);
00513     }
00514     else IKerror(31, FATAL, "BANGBANG only for Flow Currently\n");
00515   }
00516   else if (Optimization == LAGRANGIAN)
00517   {
00518     if (STEP == ONE)
00519     {
00520       /*************************************************************
00521        * CONSTRAINT TESTS BRANCH                                   *
00522        *************************************************************/
00523       if (IKMethod[OBSTACLES])
00524         avoid_obstacles (FSP_data, Jacob, dx, x_of_link,
00525                          ns, spheredata, &got_gs, datafp);
00526       if (IKMethod[JN_LIMITS])
00527         avoid_limits    (FSP_data, Jacob, dx, &got_gs, datafp);
00528     }
00529 
00530     if (Robot->PLAT.Holonomic)
00531       if (FSP_data->cn)
00532         dq = findt_with_Betas_Holonomic(FSP_data, B, H, datafp); 
00533       else
00534         dq = findt_without_Betas_Holonomic(FSP_data, B, H, datafp); 
00535     else /* Non-holonomic Platform Code */
00536        if (FSP_data->cn)
00537          dq = findt_with_Betas_Nonholonomic(FSP_data, B, H, datafp);
00538        else
00539          dq = findt_without_Betas_Nonholonomic(FSP_data, B, H, datafp); 
00540 
00541 
00542     if (STEP == TWO)
00543     {
00544       /*************************************************************
00545        *   Now add the necessary changes in angles to the current  *
00546        *   Angles and keep values withing 4 PI                     *
00547        *************************************************************/
00548       got_gs = FALSE;
00549 
00550       for (i = 0; i < M; i++)
00551       {
00552         if (fabs(FSP_data->Xelim->p[i][0]) > SMALL)
00553            dq->p[i][0] = FSP_data->Xelim->p[i][0];
00554 
00555         FSP_data->Qarray->p[i][0] += dq-> p[i][0];
00556 
00557         if (!Robot->Angles[i].Prism)
00558         {
00559           if (FSP_data->Qarray->p[i][0] >  2*PI) 
00560               FSP_data->Qarray->p[i][0] -= 2*PI;
00561           if (FSP_data->Qarray->p[i][0] < -2*PI) 
00562               FSP_data->Qarray->p[i][0] += 2*PI;
00563         }       /* end if ! prism */
00564         dq -> p[i][0] = ZERO;   /* Reset dq's in case of no constraints */
00565       }   /* end for i=1 to M */
00566 
00567 
00568       /*************************************************************
00569        * CONSTRAINT TESTS BRANCH                                   *
00570        *************************************************************/
00571       if (IKMethod[OBSTACLES])
00572         avoid_obstacles (FSP_data, Jacob, dx, x_of_link, 
00573                          ns, spheredata, &got_gs, datafp);
00574       if (IKMethod[JN_LIMITS])
00575         avoid_limits    (FSP_data, Jacob, dx, &got_gs, datafp);
00576 
00577       if (got_gs) 
00578       {
00579         Update_History(Old_DQs, dq);
00580         mat_free(dq);   /* dq has been allocated already by findt */
00581         if (Robot->PLAT.Holonomic)
00582            dq = findt_with_Betas_Holonomic(FSP_data, B, H, datafp);
00583         else
00584            dq = findt_with_Betas_Nonholonomic(FSP_data, B, H, datafp);
00585       }
00586     }
00587   }                                     /* end else LAGRANGIAN */
00588   else if (Optimization == SIMPLEX)
00589   {
00590     if (IKCriterion[0] == 4)
00591     {
00592       dq = findt_without_Betas_SIMPLX(FSP_data, B, H, datafp);
00593     }
00594     else IKerror(31, FATAL, "SIMPLX only for Flow Currently\n");
00595   }                                     /* end SIMPLEX */
00596 
00597 
00598   mat_free (B);
00599   mat_free (H);
00600 
00601   return(dq);
00602 }/*END ROUTINE*/
00603 
00604 
00605 
00606 /* ________________________________________________________
00607   | name:    OPEN_FILES                                    |
00608   | description:  This procedure opens most of the system  |
00609   |     files (spheredata is in spheres() in useful_UTILS.c|
00610   |     Also the initial condition to the differential     |
00611   |     equation (notably Qarray, initial Angles) is def-  |
00612   |     ined, and a trajectory file is read into XTraj.    |
00613   |                                                        |
00614   | inputs:  XTraj, angle output file, Qarray              |
00615   | outputs: XTraj contains trajectory, Qarray has initial |
00616   |     angle values.                                      |
00617   |________________________________________________________|
00618   | Authors:     Date:     Modifications:                  |
00619   |  F Tulloch    2/92     Who knows who started this one  |
00620   |  c hacker    10/94     restructured, removed globals   |
00621   |________________________________________________________| */
00622 int OPEN_FILES(XTraj, PoorMansFile, Qarray)
00623 char   *PoorMansFile;
00624 double  XTraj[MAX_PTS][6];
00625 MATRIX *Qarray;
00626 {                       
00627   FILE  *XYZfile, *EAfile;
00628   int    i, Num_Of_Pts,
00629          flag = -1,
00630          fatal=  1;
00631   char   tempname[20];
00632   float  temp_Q;
00633 
00634   /*********************FILE INITIALIZATION*************************/
00635   #ifdef DEBUG_OUT
00636     fprintf (stderr, "\nANGLES PRINTED TO %s.\n", PoorMansFile);
00637   #endif
00638 
00639   if (Robot->Orient)
00640     if ((EAfile     = fopen("EulerAngles",  "r")) == NULL) 
00641       { IKerror (11, OK, "EulerAngles");   flag = 0; }
00642   if ((XYZfile    = fopen("TrajectoryPts","r")) == NULL)
00643      { IKerror (11, OK, "TrajectoryPts"); flag = 0; }
00644   if ((CheezyFile = fopen(PoorMansFile,   "w")) == NULL) 
00645      { IKerror (11, OK,  PoorMansFile);   flag = 0; }
00646   if ((NormFile   = fopen("NORMFILE",     "w")) == NULL) 
00647      { IKerror (11, OK, "NORMFILE");      flag = 0; }
00648   if ((ErrorFile  = fopen("ERRORFILE",    "w")) == NULL) 
00649      { IKerror (11, OK, "ERRORFILE");     flag = 0; }
00650   if ((FLWfile    = fopen("FLOW",         "w")) == NULL) 
00651      { IKerror (11, OK, "FLOW");          flag = 0; }
00652   if ((dqfile     = fopen("Delta-qs",     "w")) == NULL) 
00653      { IKerror (11, OK, "Delta-qs");      flag = 0; }
00654   if ((distfp     = fopen("Distance",     "w")) == NULL) 
00655      { IKerror (11, OK, "Distance");      flag = 0; }
00656 
00657   if (!flag) IKerror (12, FATAL, "OPEN_FILES");
00658 
00659   /*------------------------------------------------------------------*/
00660   /* READ TRAJECTORY INTO ARRAY XTraj, MAX 3000 POINTS (makepts.h)    */
00661   /*------------------------------------------------------------------*/
00662   fscanf(XYZfile, "%d", &Num_Of_Pts);
00663   if (Num_Of_Pts > MAX_PTS)
00664   { IKerror (15, OK, "MAX_PTS in general.h"); Num_Of_Pts = MAX_PTS; }
00665 
00666   /*-----------------------------------------------------------*/
00667   /* Print first line of Q angles at t=0                       */
00668   /* terminated with a '\n'.                                   */
00669   /*-----------------------------------------------------------*/
00670   for (i = 0; i < Robot->NA; i++)
00671   {
00672     fscanf ( XYZfile, "%f", &temp_Q);
00673     if (i < M) Qarray->p[i][0] = rad(temp_Q);
00674   }
00675   fmat_pr (datafp, "Initial Q Array", Qarray);
00676   for (i = 0; i < Num_Of_Pts; i++)
00677   {
00678     fscanf(XYZfile, "%lf %lf %lf", 
00679                      &XTraj[i][0], &XTraj[i][1], &XTraj[i][2]);
00680     if (N>3)
00681     fscanf(EAfile,  "%lf %lf %lf", 
00682                      &XTraj[i][3], &XTraj[i][4], &XTraj[i][5]);
00683     /*
00684       if (DEBUG)
00685         if (N>3)
00686           fprintf(datafp,"X,Y,Z: %6.4f %6.4f %6.4f EULER: %6.4f %6.4f %6.4f\n",
00687                 XTraj[i][0],XTraj[i][1],XTraj[i][2],
00688                 XTraj[i][3],XTraj[i][4],XTraj[i][5]);
00689         else
00690           fprintf(datafp,"X,Y,Z: %6.4f %6.4f %6.4f\n",
00691                 XTraj[i][0],XTraj[i][1],XTraj[i][2]);
00692     */
00693   }
00694   fclose(XYZfile);
00695   if (N>3) fclose(EAfile);
00696 
00697   /*--------------------------------------------------------*/
00698   /* Print Header Line For IGRIP Simulation Angles File     */
00699   /* Which is in turn read in through Dave Reister's file   */
00700   /* which puts the points to the IGRIP model every so many */
00701   /* seconds to view the motion.                            */
00702   /*--------------------------------------------------------*/
00703 
00704   fprintf (CheezyFile, "M: %d N: %d\n", M, N);
00705 
00706   return (Num_Of_Pts);
00707 }                            /* END OPEN_FILES */
00708 
00709 
00710 /* ________________________________________________________
00711   | name:    init_Globals                                  |
00712   | description:  This, I'm not too proud of.  In order to |
00713   |     CheezyIGRIP work with different manipulators I had |
00714   |     to incorporate this, but unfortuneately CheezyIGRIP|
00715   |     is indeed Cheezy in many ways, one being its thirst|
00716   |     for global variables.  A,B,C,D,E,R,X and others    |
00717   |     are needed to be global for the forward kinematic  |
00718   |     which CheezyIGRIP uses.  Someone should eventually |
00719   |     remove these globals into a structure before it    |
00720   |     gets even more out of hand, but alas... tis not I. |
00721   | inputs:  none                                          |
00722   | outputs: As named, also initializes manipulator        |
00723   |________________________________________________________|
00724   | Authors:     Date:     Modifications:                  |
00725   |  c hacker     3/95     created sadly                   |
00726   |________________________________________________________| */
00727 
00728 int Init_Globals()
00729 {
00730   int i,j;
00731   float HandWidth   =0.05,
00732         HandLength  =0.05,
00733         FrontLength =ZERO,
00734         SideLength  =ZERO;
00735 
00736 
00737   if ((datafp   = fopen("data", "w")) == NULL) IKerror (11, FATAL, "data"); 
00738 
00739   /*------------------------------------------------------------------*/
00740   /* READ Users Manipulator's Parameters into System (Manipulators.c) */
00741   /*------------------------------------------------------------------*/
00742   init_ARM();       /* Initialize User_Selected Arm     */
00743 
00744   /*allocate memory for array of links*/
00745   all_links = (MATRIX **) malloc ( sizeof(MATRIX *) * Robot->NL );
00746   link_location = (MATRIX **) malloc ( sizeof(MATRIX *) * Robot->NL );
00747 
00748   /* E1-E4 are vectors to locate the 4 points used to draw the end effector */
00749 
00750   E1 = mat_malloc(4,1);  
00751   E2 = mat_malloc(4,1);  
00752   E3 = mat_malloc(4,1);
00753   E4 = mat_malloc(4,1);
00754 
00755   /* EW1-EW4 are locations of the 4 points of the EE wrt world coordinates */
00756   EW1 = mat_malloc(4,1); 
00757   EW2 = mat_malloc(4,1);   
00758   EW3 = mat_malloc(4,1);
00759   EW4 = mat_malloc(4,1);
00760  
00761   /* P1-P4 are vectors to locate the 4 points used to draw the platform */
00762   P1 = mat_malloc(4,1);  
00763   P2 = mat_malloc(4,1);   
00764   P3 = mat_malloc(4,1);
00765   P4 = mat_malloc(4,1);
00766 
00767   PW1 = mat_malloc(4,1);  
00768   PW2 = mat_malloc(4,1);   
00769   PW3 = mat_malloc(4,1);
00770   PW4 = mat_malloc(4,1);
00771 
00772   /* Also see Jacob_ROBOT.c for the use of A... */
00773 
00774   for ( i = 0; i < Robot->NL; i++) {
00775     /* location of end of links wrt world coords */
00776     all_links[i] = mat_malloc(4,1);
00777     /* location of ends of links */
00778     link_location[i] = mat_malloc(4,1);
00779   }
00780 
00781   R = mat_malloc(4,1);     /* vector to locate base of manipulator */
00782   X = mat_malloc(4,1);     /* vector to locate manip on platform */
00783   RW = mat_malloc(4,1);    /* location of manip base wrt world coords   */
00784   XW = mat_malloc(4,1);    /* location of manip on plat wrt world coords*/
00785 
00786     /* initialize all location vectors and transformation matrices */
00787   for (i=0;i<=3;i++)  
00788   { 
00789     for (j=0; j<Robot->NL; j++) {
00790       link_location[j]->p[i][0]=0;
00791     }
00792     R->p[i][0]=0;  X->p[i][0]=0;
00793     P1->p[i][0]=0;P2->p[i][0]=0;P3->p[i][0]=0;P4->p[i][0]=0;
00794     E1->p[i][0]=0;E2->p[i][0]=0;E3->p[i][0]=0;E4->p[i][0]=0;
00795   }
00796 
00797   /* drawing vectors for the manipulator */
00798   E1->p[0][0]=Robot->LINKS[Robot->NL-1]+HandLength; E1->p[2][0]=-HandWidth;
00799                                           E1->p[3][0]=1.0;
00800   E2->p[0][0]=Robot->LINKS[Robot->NL-1]           ; E2->p[2][0]=-HandWidth; 
00801                                           E2->p[3][0]=1.0;
00802   E3->p[0][0]=Robot->LINKS[Robot->NL-1]           ; E3->p[2][0]= HandWidth; 
00803                                           E3->p[3][0]=1.0;
00804   E4->p[0][0]=Robot->LINKS[Robot->NL-1]+HandLength; E4->p[2][0]= HandWidth; 
00805                                           E4->p[3][0]=1.0;
00806 
00807   /* drawing vectors for the platform */
00808   if (Robot->PLAT.Exist) {
00809     FrontLength = Robot->PLAT.Length;
00810     SideLength  = Robot->PLAT.Width;
00811   }
00812   P1->p[0][0]=-FrontLength/2; P1->p[1][0]=-SideLength/2; P1->p[3][0]=1.0;
00813   P2->p[0][0]=-FrontLength/2; P2->p[1][0]= SideLength/2; P2->p[3][0]=1.0; 
00814   P3->p[0][0]= FrontLength/2; P3->p[1][0]= SideLength/2; P3->p[3][0]=1.0;
00815   P4->p[0][0]= FrontLength/2; P4->p[1][0]=-SideLength/2; P4->p[3][0]=1.0;
00816 
00817   /* manip base offset is drawn along a local y axis */
00818   R->p[2][0]=0; R->p[3][0]=1.0;  
00819   X->p[2][0]=0; X->p[3][0]=1.0;
00820 }
00821 
00822 
00823 /* ________________________________________________________
00824   | name:    Update_History                                |
00825   | description:  Updates the history of joint angle steps.|
00826   | inputs:  none                                          |
00827   | outputs:                                               |
00828   |________________________________________________________|
00829   | Authors:     Date:     Modifications:                  |
00830   |  K Morgansen  7/95       created                       |
00831   |________________________________________________________| */
00832 
00833 void Update_History(History *Old_DQs, MATRIX *dq)
00834 {
00835 int prev;
00836 
00837 Old_DQs->whereami++;
00838 if (Old_DQs->whereami == HIST_SIZE) Old_DQs->whereami = 0;
00839 prev = Old_DQs->whereami-1;
00840 if (prev == -1) prev = HIST_SIZE - 1;
00841 
00842 mat_cp(dq, Old_DQs->dq[Old_DQs->whereami].DQ);
00843 Old_DQs->dq[Old_DQs->whereami].time=Old_DQs->dq[prev].time+0.033332;
00844          /*Old_DQs->dq[Old_DQs->whereami].time=clock()/1.0e6;      */
00845          /* this is a hack to make sure the results are consistent */
00846 
00847 }

Generated on Thu Jul 29 15:56:35 2004 for OpenSim by doxygen 1.3.6