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

robot/control/oldikor/IKOR/constraints.c

Go to the documentation of this file.
00001 /* ________________________________________________________
00002   |                                                        |
00003   | Program Name:   constraints.c                          |
00004   |________________________________________________________|
00005   |                                                        |
00006   | description: Determines if constraints are necessary   |
00007   |    for the system and if so calculates necessary betas.|
00008   |                                                        |
00009   | Procedures:                                            |
00010   |    avoid_limits    : finds limit breach & calls beta   |
00011   |    avoid_obstacles : finds obs   breach & calls beta   |
00012   |    find_intersection_sphere : As named                 |
00013   |________________________________________________________| */
00014 
00015 #include <IKOR/general.h>      /* Header File to link all others */
00016 
00017 /* ________________________________________________________
00018   | name:    avoid_limits                                  |
00019   | description:  Loops through all joint limits to find   |
00020   |     out if a joint has reached either an upper or a    |
00021   |     a lower limit.  If one has been reached and        |
00022   |     solution vectors have yet to be found, solution    |
00023   |     vectors are calculated and betas produced, other-  |
00024   |     wise, if solutions have already been found, the    |
00025   |     find beta function is called.                      |
00026   |                                                        |
00027   | inputs:  See Declarations below                        |
00028   | outputs: Calls functions to calculate betas.           |
00029   |________________________________________________________|
00030   | Authors:     Date:     Modifications:                  |
00031   |  F Tulloch     4/94    Algorithm Creation for 2 g's    |
00032   |  c hacker     10/94    Ported from 2 g's to FSP        |
00033   |                2/95    Ported to Solutions struct      |
00034   |________________________________________________________| */
00035 
00036 int avoid_limits(FSP_data, Jacob, dx, got_gs, datafp)
00037 FILE   *datafp;         /* data file declaration            */
00038 int    *got_gs;         /* get_gs or not, used for  TWOSTEP */
00039 MATRIX *Jacob,          /* needed to find soln's if TWOSTEP */
00040        *dx;             /* needed to find soln's if TWOSTEP */
00041 Solutions *FSP_data;    /* see structures.h                 */
00042 {
00043   int    qchk, ii,
00044          bound = FALSE;
00045   double distance_2_move;
00046 
00047   if (DEBUG) {
00048     fprintf(datafp,"\n  ______________________________  \n");
00049     fprintf(datafp,"\n      JOINT LIMIT AVOIDANCE       \n");
00050     fprintf(datafp,  "  ______________________________  \n\n");
00051   }
00052   for (qchk = 0; qchk < M; qchk++)
00053   {
00054               /*  limit_upper... */
00055     if  (rad(Robot->Angles[qchk].Min_limit) > FSP_data->Qarray->p[qchk][0])
00056     {   
00057       bound = TRUE;
00058       distance_2_move = 
00059         rad(Robot->Angles[qchk].Min_limit) - FSP_data->Qarray->p[qchk][0];
00060     }                        /*  limit_upper... */
00061 
00062     else      /*  limit_lower... */
00063     if (rad(Robot->Angles[qchk].Max_limit) < FSP_data->Qarray->p[qchk][0])
00064     {
00065       bound = TRUE;
00066       distance_2_move = 
00067         rad(Robot->Angles[qchk].Max_limit) - FSP_data->Qarray->p[qchk][0];
00068     }                        /*  limit_lower... */
00069 
00070   if (bound)
00071     if ( (  Robot->Angles[qchk].Prism  ) ||
00072          ((!Robot->Angles[qchk].Prism)&&(fabs(distance_2_move)>.00001))   )
00073     {
00074       bound = FALSE;
00075       if ( (STEP == TWO) && (!(*got_gs)) ) 
00076       {
00077         GET_JACOBIAN(Jacob, FSP_data->Qarray);
00078         Solution_generator ( FSP_data, Jacob, dx, datafp ); 
00079         *got_gs = TRUE;
00080       }
00081 
00082       #ifdef DEBUG_OUT
00083         fprintf(stderr, "   joint(1-%d) #%i limited  ", M, qchk+1);
00084       #endif
00085       if (DEBUG) {
00086         fprintf(datafp, "\n\njoint # %i out of range by %lf ",
00087                 qchk+1, deg(distance_2_move));
00088       }
00089       find_jl_beta(FSP_data, qchk, distance_2_move, datafp);
00090     }                           /* end if(bound)        */
00091   }                     /* end for(qchk...)     */
00092 }               /* end avoid_limits()   */
00093 
00094 /* ________________________________________________________
00095   | name:    avoid_obstacles                               |
00096   | description:  Loops through all obstacles and calls    |
00097   |     routines to determine intersection. If an obstacle |
00098   |     has been breached and solution vectors have yet to |
00099   |     be found, solution vectors are calculated and      |
00100   |     betas are produced, otherwise, if solutions have   |
00101   |     already been found, only the find beta function is |
00102   |     called.                                            |
00103   |                                                        |
00104   | inputs:  See Declarations below                        |
00105   | outputs: Calls Function to Calculate Betas             |
00106   |________________________________________________________|
00107   | Authors:     Date:     Modifications:                  |
00108   |  F Tulloch     4/94    Algorithm Creation for 2 g's    |
00109   |  c hacker     10/94    Ported from 2 g's to FSP        |
00110   |                2/95    Ported to Solutions struct      |
00111   |________________________________________________________|*/
00112 
00113 int avoid_obstacles(FSP_data, Jacob, dx, x_of_link, ns, spheredata, 
00114                     got_gs, datafp)
00115 int     ns;                     /* circ info (# of circles) */
00116 double  spheredata[4][4];       /* circ info (rad, center)  */
00117 FILE   *datafp;         /* data file declaration            */
00118 int    *got_gs;         /* get_gs or not, used for  TWOSTEP */
00119 MATRIX *Jacob,          /* needed to find soln's if TWOSTEP */
00120        *dx,             /* needed to find soln's if TWOSTEP */
00121        *x_of_link;      /* link endpts                      */
00122 Solutions *FSP_data;    /* see structures.h                 */
00123 {
00124   int    i, kk, is, ii, elbow_check=0;
00125   double newl, delta,
00126          pt1[3], pt2[3], Xj[3], normal[3];
00127 
00128   if (STEP == TWO) GET_ACTUAL_X ( FSP_data->Qarray, x_of_link );        
00129 
00130   if (DEBUG) {
00131     fprintf(datafp,"\n  ______________________________  \n");
00132     fprintf(datafp,"\n         OBSTACLE AVOIDANCE       \n");
00133     fprintf(datafp,  "  ______________________________  \n\n");
00134     fmat_pr(datafp," Position of Each Link ", x_of_link);
00135   }
00136 
00137   for (kk = 0; kk < Robot->NL; kk++)
00138   {
00139     for (i=0; i<3; i++)
00140     {
00141       pt1[i] = x_of_link->p[kk][i];      
00142       pt2[i] = x_of_link->p[kk+1][i];
00143     }
00144     if (DEBUG) {
00145       fprintf (datafp,"\nChecking LINK(0-4) %d\n", kk);
00146       fprintf (datafp," pt1 = < %f, %f, %f >\n pt2 = < %f, %f, %f >",
00147                 pt1[0],pt1[1],pt1[2],pt2[0],pt2[1],pt2[2]);
00148     }
00149 
00150     for (is = 0; is < ns; is++)
00151     {
00152       if (find_intersection_sphere(pt1, pt2, is, ns, spheredata,
00153                  &elbow_check, &newl, &delta, normal, datafp))
00154       {
00155         if ( (STEP == TWO) && (!(*got_gs)) ) 
00156         {
00157           GET_JACOBIAN(Jacob, FSP_data->Qarray);
00158           Solution_generator( FSP_data, Jacob, dx, datafp ); 
00159           *got_gs = TRUE;
00160         }
00161         for (i=0; i<3; i++)
00162           Xj[i]= x_of_link->p[kk][i] + newl*x_of_link->p[kk+1][i];
00163 
00164 
00165         #ifdef DEBUG_OUT
00166           fprintf (stderr,"   LINK %d COLLIDED\n", kk);
00167         #endif
00168         if (DEBUG) fprintf (datafp,"\tXj  = <   %4.6f,  %4.6f,  %4.6f   >\n",
00169                                                 Xj[0],  Xj[1],  Xj[2]);
00170 
00171         find_obs_beta(FSP_data, kk, &newl, delta, normal, datafp);
00172 
00173       }                         /* end if (intersection) */
00174     }                   /* end for(is=0 to ns)  */
00175   }             /* end kk loop */
00176 }       /* end avoid_obstacles() */
00177 
00178 
00179 
00180 /* ________________________________________________________
00181   | name:    find_intersection_sphere                      |
00182   | description:  For a given obstacle and link, determines|
00183   |     if that link is within the obstacles buffer zone.  |
00184   |     If so, returns closest point on the link to the    |
00185   |     center of the object, the normal vector from the   |
00186   |     center to that point, and the distance needed in   |
00187   |     to move said point to the edge of the buffer zone. |
00188   |     This information is critical to the formation of   |
00189   |     of beta values.                                    |
00190   |                                                        |
00191   | inputs:  link (pt1,pt2), sphere                        |
00192   | outputs: newl, delta, normal                           |
00193   |________________________________________________________|
00194   | Authors:     Date:     Modifications:                  |
00195   |  F Tulloch     4/94    Algorithm Creation for 2 g's    |
00196   |  c hacker      2/95    Ported to Solutions struct      |
00197   |________________________________________________________|*/
00198  
00199 int find_intersection_sphere(pt1, pt2, ws, ns, spheredata,
00200          elbow_check, newl, delta, normal, datafp)
00201 FILE   *datafp;          /* data file declaration         */
00202 int     ws;              /* which sphere                  */
00203 int    *elbow_check;     /* check if elbow of link inside */
00204 double  normal[3],       /* normal from center of sphere  */
00205        *newl,            /* closest pnt j to cntr of obs  */
00206        *delta,           /* distance pnt j is in boundary */
00207         pt1[3], pt2[3];  /* endpoints of link             */
00208 int     ns;                    /* sphere info (# spheres) */
00209 double  spheredata[4][4];      /* sphere info (rad, cntr) */
00210 {
00211   int    i, j;
00212    
00213   double x_temp,  y_temp,  z_temp,
00214          x_mid,   y_mid,   z_mid,
00215          xcenter, ycenter, zcenter, radius, 
00216          deltax,  deltay,  deltaz,
00217          b_check1, b_check2, root_chk,
00218          coeff_t_sq, coeff_t_f,
00219          t_sol_init, t_sol1, t_sol2,
00220          xsol1, xsol2,  ysol1, ysol2,  zsol1, zsol2,
00221          constant1, constant2, constant3, constantf1, constantf;
00222 
00223   xsol1 =ysol1 =zsol1 =x_temp =y_temp =z_temp =0.0;
00224 
00225   xcenter = spheredata[ws][0];
00226   ycenter = spheredata[ws][1];
00227   zcenter = spheredata[ws][2];
00228   radius  = spheredata[ws][3];
00229 
00230   /* defining constants needed in forming equations */
00231   deltax  = pt2[0] - pt1[0];
00232   deltay  = pt2[1] - pt1[1];
00233   deltaz  = pt2[2] - pt1[2];
00234 
00235   coeff_t_sq = (deltax * deltax) + (deltay * deltay) + (deltaz * deltaz);
00236 
00237 
00238   coeff_t_f = 2 * ( deltax * (pt1[0] - xcenter) +
00239                     deltay * (pt1[1] - ycenter) +
00240                     deltaz * (pt1[2] - zcenter) );
00241 
00242   constant1  = pt1[0] - xcenter;
00243   constant2  = pt1[1] - ycenter;
00244   constant3  = pt1[2] - zcenter;
00245   constantf1 =  (constant1 * constant1) + 
00246                 (constant2 * constant2) + 
00247                 (constant3 * constant3);
00248 
00249   constantf = constantf1 - SQUARE(radius);
00250 
00251 
00252   /* now that coefficients of the quadratric are defined, we solve it */
00253 
00254   b_check1 = SQUARE(coeff_t_f);
00255   b_check2 = coeff_t_sq * constantf * 4;
00256   root_chk = b_check1 - b_check2;
00257 
00258          /* now to ascertain what situation we have */
00259   if (root_chk <  0.0) return FALSE;         /* no intersection */
00260   if (root_chk == 0.0) return FALSE;         /* graze */
00261 
00262 
00263          /* root_chk > 0.0 intersection occurs */
00264   t_sol_init = sqrt(root_chk);
00265   t_sol1 = (-(coeff_t_f) + t_sol_init) / (2 * coeff_t_sq);
00266   t_sol2 = (-(coeff_t_f) - t_sol_init) / (2 * coeff_t_sq);
00267 
00268   if (DEBUG) fprintf(datafp,"\tt_sol1: %4.2f t_sol2: %4.2f \n", t_sol1, t_sol2);
00269 
00270   /************      now check t's for validity      ************/
00271 
00272              /* Does pt of inters. lie on link? */
00273   if (((0.0 > t_sol1) || (t_sol1 > 1.0)) && 
00274       ((0.0 > t_sol2) || (t_sol2 > 1.0))) 
00275   {  
00276     if (DEBUG) fprintf(datafp,"\tIntersection not on link \n");
00277     return FALSE;
00278   }
00279 
00280              /* Does pt of inters. elbow sit. */
00281   if (((0.0 > t_sol1) || (t_sol1 > 1.0)) || 
00282       ((0.0 > t_sol2) || (t_sol2 > 1.0)))
00283   {
00284     if (DEBUG) fprintf(datafp, "\tElbow Intersection!\n");
00285    *elbow_check = *elbow_check + 1;
00286 
00287     if (0.0 <= t_sol1 <= 1.0)
00288     {
00289       xsol1 = pt1[0] + (deltax * t_sol1);
00290       ysol1 = pt1[1] + (deltay * t_sol1);
00291       zsol1 = pt1[2] + (deltaz * t_sol1);
00292     }
00293 
00294     if (0.0 <= t_sol2 <= 1.0)
00295     {
00296       xsol1 = pt1[0] + (deltax * t_sol2);
00297       ysol1 = pt1[1] + (deltay * t_sol2);
00298       zsol1 = pt1[2] + (deltaz * t_sol2);
00299     }
00300 
00301     if (*elbow_check == 1)
00302     {
00303       x_temp = xsol1;        /* end of link becomes point j */
00304       y_temp = ysol1;
00305       z_temp = zsol1;
00306       return FALSE;
00307     }
00308     else if (*elbow_check % 2 == 0)
00309     {
00310       x_mid = (xsol1 + x_temp) / 2;
00311       y_mid = (ysol1 + y_temp) / 2;
00312       z_mid = (zsol1 + z_temp) / 2;
00313 
00314       *delta = radius - sqrt(((zcenter - z_mid) * (zcenter - z_mid)) 
00315                            + ((ycenter - y_mid) * (ycenter - y_mid)) 
00316                            + ((xcenter - x_mid) * (xcenter - x_mid)));
00317 
00318       normal[0] = x_mid - xcenter;
00319       normal[1] = y_mid - ycenter;
00320       normal[2] = z_mid - zcenter;
00321 
00322       *newl = 0.0;
00323     }/* end if 2nd inter.    */
00324   }  /* end elbow sit.       */
00325   else                       /* there are two inter. */
00326   {
00327     xsol1 = pt1[0] + (deltax * t_sol1);
00328     ysol1 = pt1[1] + (deltay * t_sol1);
00329     zsol1 = pt1[2] + (deltaz * t_sol1);
00330 
00331     xsol2 = pt1[0] + (deltax * t_sol2);
00332     ysol2 = pt1[1] + (deltay * t_sol2);
00333     zsol2 = pt1[2] + (deltaz * t_sol2);
00334 
00335     x_mid = (xsol1 + xsol2) / 2;
00336     y_mid = (ysol1 + ysol2) / 2;
00337     z_mid = (zsol1 + zsol2) / 2;
00338 
00339     *delta = radius - sqrt(((zcenter - z_mid) * (zcenter - z_mid)) 
00340                          + ((ycenter - y_mid) * (ycenter - y_mid)) 
00341                          + ((xcenter - x_mid) * (xcenter - x_mid)));
00342 
00343     normal[0] = x_mid - xcenter;
00344     normal[1] = y_mid - ycenter;
00345     normal[2] = z_mid - zcenter;
00346 
00347     *newl = sqrt((z_mid - pt1[2]) * (z_mid - pt1[2]) 
00348                + (y_mid - pt1[1]) * (y_mid - pt1[1]) 
00349                + (x_mid - pt1[0]) * (x_mid - pt1[0]));
00350   } /* end 2 inter. */
00351 
00352   if (DEBUG) {
00353     fprintf (datafp, "\n\tCollision with #%d circle has occured!", ws);
00354     fprintf (datafp, "\n\tnormal = <%lf,%lf,%lf>", normal[0], 
00355                                                    normal[1], 
00356                                                    normal[2]);
00357     fprintf (datafp, "\n\tCircle Delta = %lf\n", *delta);
00358   }
00359 
00360   return  TRUE;
00361 }                            /* end find inter sphere */
00362 

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